def setUp(self): self.packer = Packer() self.inst = 1 self.reg1 = 2 self.mode1 = 3 self.reg2 = 4 self.mode2 = 5
def test_get_export_data(self): settings = { 'settings': { 'unit.test': { 'domain': 'unit.test', 'length': 11, 'iterations': 5000, 'notes': 'Nice note!', 'salt': 'cGVwcGVy', 'usedCharacters': 'abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRTUVWXYZ0123456789' + '#!"§$%&/()[]{}=-_+*<>;:.', 'cDate': '2011-02-12T11:07:31', 'mDate': '2011-02-12T11:07:32' }, 'some.domain': { 'domain': 'some.domain', 'length': 4, 'iterations': 4096, 'salt': 'cGVwcGVy', 'usedCharacters': '6478593021', 'cDate': '2013-06-17T04:03:41', 'mDate': '2014-08-02T10:37:12' } }, 'synced': [] } crypter = Crypter('xyz') f = open(os.path.expanduser('~/.ctSESAM_test.pws'), 'bw') f.write(crypter.encrypt(Packer.compress(json.dumps(settings).encode('utf-8')))) f.close() self.manager.load_settings_from_file('xyz') self.assertEqual( b64encode(b'\x00' + crypter.encrypt(Packer.compress(json.dumps(settings['settings']).encode('utf-8')))), self.manager.get_export_data('xyz') )
def load_settings_from_file(self, password): """ This loads the saved settings. It is a good idea to call this method the minute you have a password. :param str password: """ if os.path.isfile(self.settings_file): file = open(self.settings_file, 'br') data = file.read() crypter = Crypter(data[:32], password) saved_settings = json.loads( str(Packer.decompress(crypter.decrypt(data[32:])), encoding='utf-8')) for domain_name in saved_settings['settings'].keys(): data_set = saved_settings['settings'][domain_name] found = False i = 0 while i < len(self.settings): setting = self.settings[i] if setting.get_domain() == domain_name: found = True if datetime.strptime( data_set['mDate'], "%Y-%m-%dT%H:%M:%S") > setting.get_m_date(): setting.load_from_dict(data_set) setting.set_synced(setting.get_domain() in saved_settings['synced']) i += 1 if not found: new_setting = PasswordSetting(domain_name) new_setting.load_from_dict(data_set) new_setting.set_synced( new_setting.get_domain() in saved_settings['synced']) self.settings.append(new_setting) file.close()
def test_load_settings_from_file(self): settings = { 'settings': { 'unit.test': { 'domain': 'unit.test', 'length': 11, 'iterations': 5000, 'notes': 'Nice note!', 'cDate': '2011-02-12T11:07:31', 'mDate': '2011-02-12T11:07:32' }, 'some.domain': { 'domain': 'some.domain', 'length': 4, 'usedCharacters': '6478593021', 'cDate': '2013-06-17T04:03:41', 'mDate': '2014-08-02T10:37:12' } }, 'synced': [] } salt = os.urandom(32) crypter = Crypter(salt, 'xyz') f = open(os.path.expanduser('~/.ctSESAM_test.pws'), 'bw') f.write(salt + struct.pack('!I', 0) + crypter.encrypt(Packer.compress(json.dumps(settings).encode('utf-8')))) f.close() self.manager.load_settings_from_file('xyz') self.assertIn('unit.test', self.manager.get_domain_list()) self.assertIn('some.domain', self.manager.get_domain_list()) self.assertEqual(11, self.manager.get_setting('unit.test').get_length()) self.assertEqual(5000, self.manager.get_setting('unit.test').get_iterations()) self.assertEqual('Nice note!', self.manager.get_setting('unit.test').get_notes()) self.assertEqual(4, self.manager.get_setting('some.domain').get_length()) self.assertEqual('6478593021', self.manager.get_setting('some.domain').get_character_set())
def get_export_data(self, password, salt=None): """ This gives you a base64 encoded string of encrypted settings data (the blob). :param password: masterpassword :type password: str :param salt: salt for the encryption: This is for testing only! Do not set it normally! :type salt: bytes :return: encrypted settings blob :rtype: str """ settings_list = self.get_settings_as_dict()['settings'] if self.remote_data: for domain_name in self.remote_data.keys(): data_set = self.remote_data[domain_name] if 'deleted' in data_set and data_set['deleted']: for i, setting_dict in enumerate(settings_list): if setting_dict['domain'] == setting_dict[ 'domain'] and datetime.strptime( data_set['mDate'], "%Y-%m-%dT%H:%M:%S") > datetime.strptime( setting_dict['mDate'], "%Y-%m-%dT%H:%M:%S"): settings_list[i] = data_set if domain_name not in settings_list.keys(): settings_list[domain_name] = { 'mDate': datetime.now(), 'deleted': True } if not salt: salt = os.urandom(32) crypter = Crypter(salt, password) return b64encode( b'\x00' + salt + crypter.encrypt(Packer.compress(json.dumps(settings_list))))
def get_export_data(self, password): """ This gives you a base64 encoded string of encrypted settings data (the blob). :param str password: :return: encrypted settings blob :rtype: str """ settings_list = self.get_settings_as_dict()['settings'] if self.remote_data: for domain_name in self.remote_data.keys(): data_set = self.remote_data[domain_name] if 'deleted' in data_set and data_set['deleted']: for i, setting_dict in enumerate(settings_list): if setting_dict['domain'] == setting_dict['domain'] and datetime.strptime( data_set['mDate'], "%Y-%m-%dT%H:%M:%S") > datetime.strptime( setting_dict['mDate'], "%Y-%m-%dT%H:%M:%S"): settings_list[i] = data_set if domain_name not in settings_list.keys(): settings_list[domain_name] = { 'mDate': datetime.now(), 'deleted': True } salt = os.urandom(32) crypter = Crypter(salt, password) return b64encode(b'\x00' + salt + crypter.encrypt(Packer.compress(json.dumps(settings_list))))
def save_settings_to_file(self, password): """ This actually saves the settings to a file on the disk. The file is encrypted so you need to supply the password. :param password: masterpassword :type password: str """ salt = os.urandom(32) crypter = Crypter(salt, password) file = open(self.settings_file, 'bw') encrypted_sync_settings = crypter.encrypt( self.sync_manager.get_binary_sync_settings()) file.write( salt + struct.pack('!I', len(encrypted_sync_settings)) + encrypted_sync_settings + crypter.encrypt( Packer.compress(json.dumps(self.get_settings_as_dict())))) file.close() try: import win32con import win32api win32api.SetFileAttributes(self.settings_file, win32con.FILE_ATTRIBUTE_HIDDEN) except ImportError: pass
def load_settings_from_file(self, password): """ This loads the saved settings. It is a good idea to call this method the minute you have a password. :param str password: """ if os.path.isfile(self.settings_file): file = open(self.settings_file, 'br') data = file.read() crypter = Crypter(data[:32], password) saved_settings = json.loads(str(Packer.decompress(crypter.decrypt(data[32:])), encoding='utf-8')) for domain_name in saved_settings['settings'].keys(): data_set = saved_settings['settings'][domain_name] found = False i = 0 while i < len(self.settings): setting = self.settings[i] if setting.get_domain() == domain_name: found = True if datetime.strptime(data_set['mDate'], "%Y-%m-%dT%H:%M:%S") > setting.get_m_date(): setting.load_from_dict(data_set) setting.set_synced(setting.get_domain() in saved_settings['synced']) i += 1 if not found: new_setting = PasswordSetting(domain_name) new_setting.load_from_dict(data_set) new_setting.set_synced(new_setting.get_domain() in saved_settings['synced']) self.settings.append(new_setting) file.close()
def update_from_sync(self, password): """ Call this method to pull settings from the sync server. :param password: the masterpassword :type password: str """ pull_successful, data = self.sync_manager.pull() if not pull_successful: print("Sync failed: No connection to the server.") return False if not len(data) > 0: return False binary_data = b64decode(data) data_version = binary_data[:1] if data_version == b'\x00': encryption_salt = binary_data[1:33] encrypted_data = binary_data[33:] crypter = Crypter(encryption_salt, password) self.remote_data = json.loads( str(Packer.decompress(crypter.decrypt(encrypted_data)), encoding='utf-8')) self.update_remote = False for domain_name in self.remote_data.keys(): data_set = self.remote_data[domain_name] found = False i = 0 while i < len(self.settings): setting = self.settings[i] if setting.get_domain() == domain_name: found = True if datetime.strptime(data_set['mDate'], "%Y-%m-%dT%H:%M:%S") > setting.get_m_date(): if 'deleted' in data_set and data_set['deleted']: self.settings.pop(i) else: setting.load_from_dict(data_set) setting.set_synced(True) self.update_remote = True i += 1 else: i += 1 else: i += 1 if not found: new_setting = PasswordSetting(domain_name) new_setting.load_from_dict(data_set) new_setting.set_synced(True) self.settings.append(new_setting) for setting in self.settings: found = False for domain_name in self.remote_data.keys(): data_set = self.remote_data[domain_name] if setting.get_domain() == domain_name: found = True if setting.get_m_date() >= datetime.strptime(data_set['mDate'], "%Y-%m-%dT%H:%M:%S"): self.update_remote = True if not found: self.update_remote = True else: print("Unknown data format version! Could not update.")
def update_from_export_data(self, password, data): """ This takes a base64 encoded string of encrypted settings (a blob) and updates the internal list of settings. :param str password: the masterpassword :param str data: base64 encoded data """ binary_data = b64decode(data) data_version = binary_data[:1] if data_version == b'\x00': encryption_salt = binary_data[1:33] encrypted_data = binary_data[:33] crypter = Crypter(encryption_salt, password) self.remote_data = json.loads( str(Packer.decompress(crypter.decrypt(encrypted_data)), encoding='utf-8')) update_remote = False for domain_name in self.remote_data.keys(): data_set = self.remote_data[domain_name] found = False i = 0 while i < len(self.settings): setting = self.settings[i] if setting.get_domain() == domain_name: found = True if datetime.strptime( data_set['mDate'], "%Y-%m-%dT%H:%M:%S") > setting.get_m_date(): if 'deleted' in data_set and data_set['deleted']: self.settings.pop(i) else: setting.load_from_dict(data_set) setting.set_synced(True) i += 1 else: i += 1 update_remote = True else: i += 1 if not found: new_setting = PasswordSetting(domain_name) new_setting.load_from_dict(data_set) new_setting.set_synced(True) self.settings.append(new_setting) for setting in self.settings: found = False for domain_name in self.remote_data.keys(): data_set = self.remote_data[domain_name] if setting.get_domain() == domain_name: found = True if setting.get_m_date() >= datetime.strptime( data_set['mDate'], "%Y-%m-%dT%H:%M:%S"): update_remote = True if not found: update_remote = True return update_remote else: print("Unknown data format version! Could not update.") return False
def test_get_export_data(self): settings = { 'settings': { 'unit.test': { 'domain': 'unit.test', 'length': 11, 'iterations': 5000, 'notes': 'Nice note!', 'salt': 'cGVwcGVy', 'usedCharacters': 'abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRTUVWXYZ0123456789' + '#!"§$%&/()[]{}=-_+*<>;:.', 'cDate': '2011-02-12T11:07:31', 'mDate': '2011-02-12T11:07:32' }, 'some.domain': { 'domain': 'some.domain', 'length': 4, 'iterations': 4096, 'salt': 'cGVwcGVy', 'usedCharacters': '6478593021', 'cDate': '2013-06-17T04:03:41', 'mDate': '2014-08-02T10:37:12' } }, 'synced': [] } crypter = Crypter('xyz') f = open(os.path.expanduser('~/.ctSESAM_test.pws'), 'bw') f.write( crypter.encrypt( Packer.compress(json.dumps(settings).encode('utf-8')))) f.close() self.manager.load_settings_from_file('xyz') self.assertEqual( b64encode(b'\x00' + crypter.encrypt( Packer.compress( json.dumps(settings['settings']).encode('utf-8')))), self.manager.get_export_data('xyz'))
class Test_Packer(unittest.TestCase): def setUp(self): self.packer = Packer() self.inst = 1 self.reg1 = 2 self.mode1 = 3 self.reg2 = 4 self.mode2 = 5 def test_pack_inst(self): """ test that a new instruction is encoded """ code = self.packer.pack(self.inst, self.reg1, self.mode1, self.reg2, self.mode2) self.assertEquals(code, 5349) def test_unpack_inst(self): self.assertEquals( self.packer.unpack(5349), [self.inst, self.reg1, self.mode1, self.reg2, self.mode2])
def update_from_export_data(self, password, data): """ This takes a base64 encoded string of encrypted settings (a blob) and updates the internal list of settings. :param str password: the masterpassword :param str data: base64 encoded data """ binary_data = b64decode(data) data_version = binary_data[:1] if data_version == b'\x00': encryption_salt = binary_data[1:33] encrypted_data = binary_data[:33] crypter = Crypter(encryption_salt, password) self.remote_data = json.loads(str(Packer.decompress(crypter.decrypt(encrypted_data)), encoding='utf-8')) update_remote = False for domain_name in self.remote_data.keys(): data_set = self.remote_data[domain_name] found = False i = 0 while i < len(self.settings): setting = self.settings[i] if setting.get_domain() == domain_name: found = True if datetime.strptime(data_set['mDate'], "%Y-%m-%dT%H:%M:%S") > setting.get_m_date(): if 'deleted' in data_set and data_set['deleted']: self.settings.pop(i) else: setting.load_from_dict(data_set) setting.set_synced(True) i += 1 else: i += 1 update_remote = True else: i += 1 if not found: new_setting = PasswordSetting(domain_name) new_setting.load_from_dict(data_set) new_setting.set_synced(True) self.settings.append(new_setting) for setting in self.settings: found = False for domain_name in self.remote_data.keys(): data_set = self.remote_data[domain_name] if setting.get_domain() == domain_name: found = True if setting.get_m_date() >= datetime.strptime(data_set['mDate'], "%Y-%m-%dT%H:%M:%S"): update_remote = True if not found: update_remote = True return update_remote else: print("Unknown data format version! Could not update.") return False
def test_save_settings_to_file(self): self.manager.get_setting('abc.de') new_setting = PasswordSetting('hugo.com') new_setting.set_length(12) self.manager.save_setting(new_setting) self.manager.save_settings_to_file('xyz') f = open(os.path.expanduser('~/.ctSESAM_test.pws'), 'br') crypter = Crypter('xyz') data = json.loads(Packer.decompress(crypter.decrypt(f.read())).decode('utf8')) f.close() self.assertEqual('abc.de', data['settings']['abc.de']['domain']) self.assertEqual(10, data['settings']['abc.de']['length']) self.assertEqual('hugo.com', data['settings']['hugo.com']['domain']) self.assertEqual(12, data['settings']['hugo.com']['length'])
def test_save_settings_to_file(self): self.manager.get_setting('abc.de') new_setting = PasswordSetting('hugo.com') new_setting.set_length(12) self.manager.set_setting(new_setting) self.manager.save_settings_to_file('xyz') with open(os.path.expanduser('~/.ctSESAM_test.pws'), 'br') as f: data = f.read() crypter = Crypter(data[:32], 'xyz') sync_settings_len = struct.unpack('!I', data[32:36])[0] data = json.loads(Packer.decompress(crypter.decrypt(data[36+sync_settings_len:])).decode('utf8')) self.assertEqual('abc.de', data['settings']['abc.de']['domain']) self.assertEqual(10, data['settings']['abc.de']['length']) self.assertEqual('hugo.com', data['settings']['hugo.com']['domain']) self.assertEqual(12, data['settings']['hugo.com']['length'])
def test_save_settings_to_file(self): self.manager.get_setting('abc.de') new_setting = PasswordSetting('hugo.com') new_setting.set_length(12) self.manager.save_setting(new_setting) self.manager.save_settings_to_file('xyz') f = open(os.path.expanduser('~/.ctSESAM_test.pws'), 'br') crypter = Crypter('xyz') data = json.loads( Packer.decompress(crypter.decrypt(f.read())).decode('utf8')) f.close() self.assertEqual('abc.de', data['settings']['abc.de']['domain']) self.assertEqual(10, data['settings']['abc.de']['length']) self.assertEqual('hugo.com', data['settings']['hugo.com']['domain']) self.assertEqual(12, data['settings']['hugo.com']['length'])
def get_binary_sync_settings(self): """ returns packed sync settings :return: binary settings :rtype: bytes """ if self.sync: return Packer.compress(json.dumps({ "server-address": self.server_address, "username": self.username, "password": self.password, "certificate": self.certificate }).encode('utf-8')) else: return b''
def load_settings_from_file(self, password, omit_sync_settings_questions=False): """ This loads the saved settings. It is a good idea to call this method the minute you have a password. :param str password: masterpassword :param bool omit_sync_settings_questions: do not ask for questions? (Defalut: False) :type password: str """ if os.path.isfile(self.settings_file): file = open(self.settings_file, 'br') data = file.read() crypter = Crypter(data[:32], password) sync_settings_len = struct.unpack('!I', data[32:36])[0] if sync_settings_len > 0: self.sync_manager.load_binary_sync_settings( crypter.decrypt(data[36:36 + sync_settings_len])) saved_settings = json.loads( str(Packer.decompress( crypter.decrypt(data[36 + sync_settings_len:])), encoding='utf-8')) for domain_name in saved_settings['settings'].keys(): data_set = saved_settings['settings'][domain_name] found = False i = 0 while i < len(self.settings): setting = self.settings[i] if setting.get_domain() == domain_name: found = True if datetime.strptime( data_set['mDate'], "%Y-%m-%dT%H:%M:%S") > setting.get_m_date(): setting.load_from_dict(data_set) setting.set_synced(setting.get_domain() in saved_settings['synced']) i += 1 if not found: new_setting = PasswordSetting(domain_name) new_setting.load_from_dict(data_set) new_setting.set_synced( new_setting.get_domain() in saved_settings['synced']) self.settings.append(new_setting) file.close() else: if not omit_sync_settings_questions: self.sync_manager.ask_for_sync_settings()
def save_settings_to_file(self, password): """ This actually saves the settings to a file on the disk. The file is encrypted so you need to supply the password. :param str password: """ salt = os.urandom(32) crypter = Crypter(salt, password) file = open(self.settings_file, 'bw') file.write(salt + crypter.encrypt(Packer.compress(json.dumps(self.get_settings_as_dict())))) file.close() try: import win32con import win32api win32api.SetFileAttributes(self.settings_file, win32con.FILE_ATTRIBUTE_HIDDEN) except ImportError: pass
def save_settings_to_file(self, password): """ This actually saves the settings to a file on the disk. The file is encrypted so you need to supply the password. :param str password: """ salt = os.urandom(32) crypter = Crypter(salt, password) file = open(self.settings_file, 'bw') file.write(salt + crypter.encrypt( Packer.compress(json.dumps(self.get_settings_as_dict())))) file.close() try: import win32con import win32api win32api.SetFileAttributes(self.settings_file, win32con.FILE_ATTRIBUTE_HIDDEN) except ImportError: pass
def pull(self): """ Returns some mock data tor the sync test. :return: base64 mock data blob :rtype: (bool, str) """ remote_data = { 'unit.test': { 'domain': 'unit.test', 'length': 12, 'iterations': 5001, 'notes': 'another note!', 'salt': 'cGVwcGVy', 'usedCharacters': 'abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRTUVWXYZ0123456789', 'cDate': '2011-02-12T11:07:31', 'mDate': '2013-07-12T14:46:11' }, 'some.domain': { 'domain': 'some.domain', 'length': 4, 'iterations': 4097, 'salt': 'cGVwcGVy', 'usedCharacters': '6478593021', 'cDate': '2013-06-17T04:03:41', 'mDate': '2014-08-02T10:37:11' }, 'third.domain': { 'domain': 'third.domain', 'length': 10, 'iterations': 4098, 'salt': 'cGVwcGVy', 'usedCharacters': 'aeiou', 'cDate': '2013-06-17T04:03:41', 'mDate': '2014-08-02T10:37:11' } } salt = os.urandom(32) crypter = Crypter(salt, 'xyz') return True, str(b64encode(b'\x00' + salt + crypter.encrypt( Packer.compress(json.dumps(remote_data).encode('utf-8')))), encoding='utf-8')
def test_update_from_sync(self): settings = { 'settings': { 'unit.test': { 'domain': 'unit.test', 'length': 11, 'iterations': 5000, 'notes': 'Nice note!', 'salt': 'cGVwcGVy', 'usedCharacters': 'abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRTUVWXYZ0123456789' + '#!"§$%&/()[]{}=-_+*<>;:.', 'cDate': '2011-02-12T11:07:31', 'mDate': '2011-02-12T11:07:32' }, 'some.domain': { 'domain': 'some.domain', 'length': 4, 'iterations': 4096, 'salt': 'cGVwcGVy', 'usedCharacters': '6478593021', 'cDate': '2013-06-17T04:03:41', 'mDate': '2014-08-02T10:37:12' } }, 'synced': [] } salt = os.urandom(32) crypter = Crypter(salt, 'xyz') f = open(os.path.expanduser('~/.ctSESAM_test.pws'), 'bw') f.write(salt + struct.pack('!I', 0) + crypter.encrypt( Packer.compress(json.dumps(settings).encode('utf-8')))) f.close() self.manager.load_settings_from_file('xyz') self.manager.sync_manager = MockSyncManager() self.manager.update_from_sync('xyz') self.assertIn('unit.test', self.manager.get_domain_list()) self.assertIn('some.domain', self.manager.get_domain_list()) self.assertIn('third.domain', self.manager.get_domain_list()) self.assertEqual(5001, self.manager.get_setting('unit.test').get_iterations()) self.assertEqual(4096, self.manager.get_setting('some.domain').get_iterations()) self.assertEqual(4098, self.manager.get_setting('third.domain').get_iterations())
def save_settings_to_file(self, password): """ This actually saves the settings to a file on the disk. The file is encrypted so you need to supply the password. :param password: masterpassword :type password: str """ salt = os.urandom(32) crypter = Crypter(salt, password) file = open(self.settings_file, 'bw') encrypted_sync_settings = crypter.encrypt(self.sync_manager.get_binary_sync_settings()) file.write(salt + struct.pack('!I', len(encrypted_sync_settings)) + encrypted_sync_settings + crypter.encrypt(Packer.compress(json.dumps(self.get_settings_as_dict())))) file.close() try: import win32con import win32api win32api.SetFileAttributes(self.settings_file, win32con.FILE_ATTRIBUTE_HIDDEN) except ImportError: pass
def load_settings_from_file(self, password, omit_sync_settings_questions=False): """ This loads the saved settings. It is a good idea to call this method the minute you have a password. :param str password: masterpassword :param bool omit_sync_settings_questions: do not ask for questions? (Defalut: False) :type password: str """ if os.path.isfile(self.settings_file): file = open(self.settings_file, 'br') data = file.read() crypter = Crypter(data[:32], password) sync_settings_len = struct.unpack('!I', data[32:36])[0] if sync_settings_len > 0: self.sync_manager.load_binary_sync_settings(crypter.decrypt(data[36:36+sync_settings_len])) saved_settings = json.loads(str(Packer.decompress(crypter.decrypt(data[36+sync_settings_len:])), encoding='utf-8')) for domain_name in saved_settings['settings'].keys(): data_set = saved_settings['settings'][domain_name] found = False i = 0 while i < len(self.settings): setting = self.settings[i] if setting.get_domain() == domain_name: found = True if datetime.strptime(data_set['mDate'], "%Y-%m-%dT%H:%M:%S") > setting.get_m_date(): setting.load_from_dict(data_set) setting.set_synced(setting.get_domain() in saved_settings['synced']) i += 1 if not found: new_setting = PasswordSetting(domain_name) new_setting.load_from_dict(data_set) new_setting.set_synced(new_setting.get_domain() in saved_settings['synced']) self.settings.append(new_setting) file.close() else: if not omit_sync_settings_questions: self.sync_manager.ask_for_sync_settings()
def load_binary_sync_settings(self, data): """ loads sync settings :param bytes data: packed json data of sync settings """ settings_dict = json.loads(str(Packer.decompress(data), encoding='utf-8')) if "server-address" in settings_dict and \ "username" in settings_dict and \ "password" in settings_dict and \ "certificate" in settings_dict: self.server_address = settings_dict["server-address"] self.username = settings_dict["username"] self.password = settings_dict["password"] self.certificate = settings_dict["certificate"] if self.certificate_file: self.certificate_file.close() self.certificate_file = NamedTemporaryFile() self.certificate_file.write(self.certificate.encode('utf-8')) self.certificate_file.seek(0) self.create_sync() else: print("Sync settings konnten nicht geladen werden.")
def test_decompress(self): self.assertEqual( b'Some packable information', Packer.decompress(b64decode("AAAAGXjaC87PTVUoSEzOTkzKSVXIzEvLL8pNLMnMzwMAedUJrg==")))
def test_compress(self): packed_data = Packer.compress("Some packable information") self.assertEqual(b'AAAAGXjaC87PTVUoSEzOTkzKSVXIzEvLL8pNLMnMzwMAedUJrg==', b64encode(packed_data))
def buildFloor(self): """ Creates a Cell for each location on the floor and creates objects that will initially start on the Floor. Initial Point locations for the warehouse Floor are set here. Goes through every Point location within Floor and creates a new Cell for it. If there is an object that has a matching Point location as the new Cell, that object is added to the Cell as well Creates Picker, Packer, Robots, Chargers, as well as the DockArea, BeltArea, and ShelveAreas Current values are for a 10x10 floor layout Called during initialization """ # Set Locations for objects and create instances picker_location = Point(1, 7) picker = Picker(picker_location) packer_location = Point(1, 4) packer = Packer(packer_location) shipping_dock = DockArea( [Point(0, 0), Point(1, 0), Point(0, 1), Point(1, 1)]) shipping_dock_corner = Point(0, 1) chargers = [ Charger(Point(2, 9)), Charger(Point(3, 9)), Charger(Point(4, 9)), Charger(Point(5, 9)), Charger(Point(6, 9)) ] robots = [ Robot('A', Point(2, 9)), Robot('B', Point(3, 9)), Robot('C', Point(4, 9)), Robot('D', Point(5, 9)), Robot('E', Point(6, 9)) ] shelf_areas = [ShelfArea(Point(5, 1), 5), ShelfArea(Point(5, 5), 5)] belt_length = picker_location.y - shipping_dock_corner.y belt_areas = [ BeltArea(self, Point(picker_location.x - 1, picker_location.y), belt_length) ] # Once everything has been created, give them to Floor self.picker = picker self.packer = packer self.shipping_dock = shipping_dock self.shipping_dock_corner = shipping_dock_corner self.chargers = chargers self.robots = robots self.shelf_areas = shelf_areas self.belt_areas = belt_areas # For each Point location in the warehouse, create a new Cell and if there is an object # that has a matching Point location, add that object to the Cell for x in range(0, self.warehouse_width): for y in range(0, self.warehouse_depth): point = Point(x, y) # Create Cell for point location cell = Cell(point) # Check if Point location matches Picker location if picker.getPickLocation( ).x == point.x and picker.getPickLocation().y == point.y: cell.setContents(self.picker) # Check if Point location matched Packer location if self.packer.getLocation( ).x == point.x and packer.getLocation().y == point.y: cell.setContents(self.packer) # Check if Point location matched Dock Area location for p in self.shipping_dock.points: if p.x == point.x and p.y == point.y: cell.setContents(self.shipping_dock) # Check the Chargers to see if any match Point location for charger in self.chargers: if charger.location.x == point.x and charger.location.y == point.y: cell.setContents(charger) # Check the Robots to see if any match Point location for robot in self.robots: if robot.location.x == point.x and robot.location.y == point.y: cell.setContents(robot) robot.setCell(cell) # Check the Shelf Areas for Shelves that match Point location # Cell are already created within Shelf Area so use those Cells if matching location for s in self.shelf_areas: if s.hasWithin(point): cell = s.getCell(point) assert cell is not None # Check the Belt Areas for Belts that match Point location # Cell are already created within Belt Area so use those Cells if matching location for b in self.belt_areas: if b.isWithin(point): cell = b.getCell(point) assert cell is not None # Adds to the dictionary as {Point: Cell} self.all_points.update({str(point): cell})
def update_from_sync(self, password): """ Call this method to pull settings from the sync server. :param password: the masterpassword :type password: str """ pull_successful, data = self.sync_manager.pull() if not pull_successful: print("Sync failed: No connection to the server.") return False if not len(data) > 0: return False binary_data = b64decode(data) data_version = binary_data[:1] if data_version == b'\x00': encryption_salt = binary_data[1:33] encrypted_data = binary_data[33:] crypter = Crypter(encryption_salt, password) self.remote_data = json.loads( str(Packer.decompress(crypter.decrypt(encrypted_data)), encoding='utf-8')) self.update_remote = False for domain_name in self.remote_data.keys(): data_set = self.remote_data[domain_name] found = False i = 0 while i < len(self.settings): setting = self.settings[i] if setting.get_domain() == domain_name: found = True if datetime.strptime( data_set['mDate'], "%Y-%m-%dT%H:%M:%S") > setting.get_m_date(): if 'deleted' in data_set and data_set['deleted']: self.settings.pop(i) else: setting.load_from_dict(data_set) setting.set_synced(True) self.update_remote = True i += 1 else: i += 1 else: i += 1 if not found: new_setting = PasswordSetting(domain_name) new_setting.load_from_dict(data_set) new_setting.set_synced(True) self.settings.append(new_setting) for setting in self.settings: found = False for domain_name in self.remote_data.keys(): data_set = self.remote_data[domain_name] if setting.get_domain() == domain_name: found = True if setting.get_m_date() >= datetime.strptime( data_set['mDate'], "%Y-%m-%dT%H:%M:%S"): self.update_remote = True if not found: self.update_remote = True else: print("Unknown data format version! Could not update.")