def queue_file(window: 'TxWindow', settings: 'Settings', queues: 'QueueDict') -> None: """Ask file path and load file data. In TFC there are two ways to send a file. For traffic masking, the file is loaded and sent inside normal messages using assembly packet headers dedicated for file transmission. This transmission is much slower, so the File object will determine metadata about the transmission's estimated transfer time, number of packets and the name and size of file. This information is inserted to the first assembly packet so that the recipient can observe the transmission progress from file transfer window. When traffic masking is disabled, file transmission is much faster as the file is only encrypted and transferred over serial once before the Relay Program multi-casts the ciphertext to each specified recipient. See the send_file docstring (below) for more details. """ path = ask_path_gui("Select file to send...", settings, get_file=True) if path.endswith( ('tx_contacts', 'tx_groups', 'tx_keys', 'tx_login_data', 'tx_settings', 'rx_contacts', 'rx_groups', 'rx_keys', 'rx_login_data', 'rx_settings', 'tx_serial_settings.json', 'nc_serial_settings.json', 'rx_serial_settings.json', 'tx_onion_db')): raise FunctionReturn("Error: Can't send TFC database.", head_clear=True) if not settings.traffic_masking: send_file(path, settings, queues, window) return file = File(path, window, settings) assembly_packets = split_to_assembly_packets(file.plaintext, FILE) if settings.confirm_sent_files: try: if not yes( f"Send {file.name.decode()} ({file.size_hr}) to {window.type_print} {window.name} " f"({len(assembly_packets)} packets, time: {file.time_hr})?" ): raise FunctionReturn("File selection aborted.", head_clear=True) except (EOFError, KeyboardInterrupt): raise FunctionReturn("File selection aborted.", head_clear=True) queue_assembly_packets(assembly_packets, FILE, settings, queues, window, log_as_ph=True)
def test_small_file(self) -> None: # Setup input_data = os.urandom(5) with open('testfile.txt', 'wb+') as f: f.write(input_data) self.settings.traffic_masking = True self.settings.multi_packet_random_delay = True # Test file = File('./testfile.txt', *self.args) self.assertEqual(file.name, b'testfile.txt') self.assertEqual(file.size_hr, '5.0B') self.assertEqual(len(file.plaintext), 114) self.assertIsInstance(file.plaintext, bytes)
def test_large_file_and_local_testing(self) -> None: # Setup input_data = os.urandom(2000) with open('testfile.txt', 'wb+') as f: f.write(input_data) self.settings.multi_packet_random_delay = True self.settings.local_testing_mode = True self.window.window_contacts = [create_contact(c) for c in ['Alice', 'Bob']] # Test file = File('./testfile.txt', *self.args) self.assertEqual(file.name, b'testfile.txt') self.assertEqual(len(file.plaintext), 2112) self.assertEqual(file.size_hr, '2.0KB') self.assertIsInstance(file.plaintext, bytes) self.assertEqual(file.time_hr, '0:01:48')