def populate_accounts(self): keys = self.load_private_keys() self._accounts_list.items = [] for key in keys: account = self._plugin._web3.account_from_key(key) address = account.address.lower() short_address = utils.short_address(address) filepath = os.path.join(os.path.dirname(__file__), '../temp/blockies/' + address + '.png') with open(filepath, 'wb') as png: blockie = blockies.create(address, scale=64) png.write(blockie) png.close() account.blockie = filepath account.short_address = short_address account_item = self._prefab_account_item.clone() account_item.enabled = True button = account_item.get_content() button.register_pressed_callback( partial(self._plugin.select_account, account)) account_item.find_node('Blockie').add_new_image(filepath) account_item.find_node( 'Address').get_content().text_value = short_address self._accounts_list.items.append(account_item) self._plugin.refresh_menu()
async def test_tokens(self): image = blockies.create(TEST_ADDRESS, size=8, scale=12) hasher = hashlib.md5() hasher.update(image) hash = hasher.hexdigest() async with self.pool.acquire() as con: await con.execute( "INSERT INTO tokens " "(address, symbol, name, decimals, icon, hash) " "VALUES ($1, $2, $3, $4, $5, $6)", "1", "ABC", "Awesome Balls Currency Token", 18, image, hash) await con.execute( "INSERT INTO tokens " "(address, symbol, name, decimals, icon, hash) " "VALUES ($1, $2, $3, $4, $5, $6)", "2", "YAC", "Yet Another Currency Token", 2, image, hash) resp = await self.fetch("/tokens", method="GET") self.assertResponseCodeEqual(resp, 200) body = json_decode(resp.body) self.assertEqual(len(body['tokens']), 2) for token in body['tokens']: icon_url = token['icon_url'] resp = await self.fetch(icon_url, method="GET") self.assertResponseCodeEqual(resp, 200) self.assertEqual(resp.headers.get('Content-Type'), 'image/png') self.assertEqual(resp.body, image)
async def get(self, address, format, include_body=True): format = format.upper() if format == 'JPG': format = 'JPEG' if format not in self.FORMAT_MAP.keys(): raise HTTPError(404) data = blockies.create(address, size=8, scale=12, format=format.upper()) hasher = hashlib.md5() hasher.update(data) cache_hash = hasher.hexdigest() await self.handle_file_response(data, self.FORMAT_MAP[format], cache_hash, datetime.datetime(2017, 1, 1))
async def test_send_large_file(self): """Tests uploading a large avatar and makes sure it doesn't block other processes""" capitalised = 'BobSmith' async with self.pool.acquire() as con: await con.execute( "INSERT INTO users (username, toshi_id) VALUES ($1, $2)", capitalised, TEST_ADDRESS) # saves a generated file in the /tmp dir to speed up # multiple runs of the same test tmpfile = "/tmp/toshi-testing-large-file-test-2390.jpg" if os.path.exists(tmpfile): jpeg = open(tmpfile, 'rb').read() else: # generates a file just under 100mb (100mb being the max size upload supported) jpeg = blockies.create(TEST_ADDRESS_2, size=2390, scale=12, format='JPEG') with open(tmpfile, 'wb') as f: f.write(jpeg) print("size: {} MB".format(len(jpeg) / 1024 / 1024)) boundary = uuid4().hex headers = { 'Content-Type': 'multipart/form-data; boundary={}'.format(boundary) } files = [('avatar.jpg', jpeg)] body = body_producer(boundary, files) f1 = self.fetch_signed("/user", signing_key=TEST_PRIVATE_KEY, method="PUT", body=body, headers=headers) # make sure the avatar upload has begun await asyncio.sleep(1) f2 = self.fetch("/v1/user/{}".format(TEST_ADDRESS), method="GET") def f1done(r): assert f2.done() def f2done(r): assert not f1.done() loop = IOLoop.current() loop.add_future(f1, f1done) loop.add_future(f2, f2done) await asyncio.wait([to_asyncio_future(f) for f in [f1, f2]], timeout=5)
async def test_update_user_avatar_with_specific_toshi_id_handler(self): capitalised = 'BobSmith' async with self.pool.acquire() as con: await con.execute( "INSERT INTO users (username, toshi_id) VALUES ($1, $2)", capitalised, TEST_ADDRESS) boundary = uuid4().hex headers = { 'Content-Type': 'multipart/form-data; boundary={}'.format(boundary) } png = blockies.create(TEST_PAYMENT_ADDRESS, size=8, scale=12, format='PNG') files = [('image.png', png)] body = body_producer(boundary, files) resp = await self.fetch_signed("/user/{}".format(TEST_ADDRESS), signing_key=TEST_PRIVATE_KEY, method="PUT", body=body, headers=headers) self.assertResponseCodeEqual(resp, 200) async with self.pool.acquire() as con: urow = await con.fetchrow( "SELECT * FROM users WHERE toshi_id = $1", TEST_ADDRESS) self.assertIsNotNone(urow) self.assertIsNotNone(urow['avatar']) self.assertIsNotNone( regex.match( "\/[^\/]+\/public\/avatar\/{}_[a-f0-9]{{{}}}\.png".format( TEST_ADDRESS, AVATAR_URL_HASH_LENGTH), urllib.parse.urlparse(urow['avatar']).path), urow['avatar']) resp = await self.fetch(urow['avatar'], method="GET") self.assertEqual( resp.code, 200, "Got unexpected {} for url: {}".format(resp.code, urow['avatar'])) self.assertEqual(resp.body, png)
async def test_tokens(self): image = blockies.create(TEST_ADDRESS, size=8, scale=12) hasher = hashlib.md5() hasher.update(image) hash = hasher.hexdigest() async with self.pool.acquire() as con: await con.execute( "INSERT INTO tokens " "(contract_address, symbol, name, decimals, icon, hash, format) " "VALUES ($1, $2, $3, $4, $5, $6, $7)", "0x1111111111111111111111111111111111111111", "ABC", "Awesome Balls Currency Token", 18, image, hash, 'png') await con.execute( "INSERT INTO tokens " "(contract_address, symbol, name, decimals) " "VALUES ($1, $2, $3, $4)", "0x2222222222222222222222222222222222222222", "YAC", "Yet Another Currency Token", 2) resp = await self.fetch("/tokens", method="GET") self.assertResponseCodeEqual(resp, 200) body = json_decode(resp.body) self.assertEqual(len(body['tokens']), 2) for token in body['tokens']: icon_url = token['icon'] if token['symbol'] == "YAC": self.assertIsNone(token['icon']) else: self.assertEqual( self.get_url("/token/{}.png".format( token['contract_address'])), icon_url) resp = await self.fetch(icon_url, method="GET") self.assertResponseCodeEqual(resp, 200) self.assertEqual(resp.headers.get('Content-Type'), 'image/png') self.assertEqual(resp.body, image) resp = await self.fetch( "/token/0x0000000000000000000000000000000000000000.png") self.assertResponseCodeEqual(resp, 404)
async def test_update_user_avatar_with_specific_toshi_id_handler(self): capitalised = 'BobSmith' async with self.pool.acquire() as con: await con.execute( "INSERT INTO users (username, toshi_id) VALUES ($1, $2)", capitalised, TEST_ADDRESS) boundary = uuid4().hex headers = { 'Content-Type': 'multipart/form-data; boundary={}'.format(boundary) } png = blockies.create(TEST_PAYMENT_ADDRESS, size=8, scale=12, format='PNG') files = [('image.png', png)] body = body_producer(boundary, files) resp = await self.fetch_signed("/user/{}".format(TEST_ADDRESS), signing_key=TEST_PRIVATE_KEY, method="PUT", body=body, headers=headers) self.assertResponseCodeEqual(resp, 200) async with self.pool.acquire() as con: arow = await con.fetchrow( "SELECT * FROM avatars WHERE toshi_id = $1", TEST_ADDRESS) urow = await con.fetchrow( "SELECT * FROM users WHERE toshi_id = $1", TEST_ADDRESS) self.assertIsNotNone(arow) self.assertEqual(arow['img'], files[0][1]) self.assertIsNotNone(urow) self.assertIsNotNone(urow['avatar']) self.assertEqual( urow['avatar'], "/avatar/{}_{}.png".format(TEST_ADDRESS, arow['hash'][:AVATAR_URL_HASH_LENGTH]))
async def test_update_user_avatar(self): capitalised = 'BobSmith' async with self.pool.acquire() as con: await con.execute( "INSERT INTO users (username, toshi_id) VALUES ($1, $2)", capitalised, TEST_ADDRESS) boundary = uuid4().hex headers = { 'Content-Type': 'multipart/form-data; boundary={}'.format(boundary) } png = blockies.create(TEST_PAYMENT_ADDRESS, size=8, scale=12, format='PNG') files = [('image.png', png)] body = body_producer(boundary, files) resp = await self.fetch_signed("/user", signing_key=TEST_PRIVATE_KEY, method="PUT", body=body, headers=headers) self.assertResponseCodeEqual(resp, 200) async with self.pool.acquire() as con: urow = await con.fetchrow( "SELECT * FROM users WHERE toshi_id = $1", TEST_ADDRESS) self.assertIsNotNone(urow) self.assertIsNotNone(urow['avatar']) self.assertIsNotNone( regex.match( "\/[^\/]+\/public\/avatar\/{}_[a-f0-9]{{{}}}\.png".format( TEST_ADDRESS, AVATAR_URL_HASH_LENGTH), urllib.parse.urlparse(urow['avatar']).path), urow['avatar']) first_avatar_url = urow['avatar'] resp = await self.fetch(first_avatar_url, method="GET") self.assertEqual( resp.code, 200, "Got unexpected {} for url: {}".format(resp.code, first_avatar_url)) # easy to test png, it doesn't change so easily when "double" saved self.assertEqual(resp.body, png) self.assertIn('Etag', resp.headers) last_etag = resp.headers['Etag'] self.assertIn('Last-Modified', resp.headers) last_modified = resp.headers['Last-Modified'] # try update with jpeg jpeg = blockies.create(TEST_ADDRESS_2, size=8, scale=12, format='JPEG') # rotate jpeg # TODO: figure out if there's actually a way to test that # this is working as expected jpeg = Image.open(BytesIO(jpeg)).rotate(90) stream = BytesIO() # generate exif info for rotation exif_dict = { "0th": { piexif.ImageIFD.XResolution: (jpeg.size[0], 1), piexif.ImageIFD.YResolution: (jpeg.size[1], 1), piexif.ImageIFD.Orientation: 8 } } jpeg.save(stream, format="JPEG", exif=piexif.dump(exif_dict)) jpeg = stream.getbuffer().tobytes() files = [('image.jpg', jpeg)] body = body_producer(boundary, files) resp = await self.fetch_signed("/user", signing_key=TEST_PRIVATE_KEY, method="PUT", body=body, headers=headers) self.assertResponseCodeEqual(resp, 200) # ensure we got a tracking event self.assertEqual((await self.next_tracking_event())[0], encode_id(TEST_ADDRESS)) async with self.pool.acquire() as con: urow = await con.fetchrow( "SELECT * FROM users WHERE toshi_id = $1", TEST_ADDRESS) self.assertIsNotNone(urow) self.assertIsNotNone(urow['avatar']) self.assertIsNotNone( regex.match( "\/[^\/]+\/public\/avatar\/{}_[a-f0-9]{{{}}}\.jpg".format( TEST_ADDRESS, AVATAR_URL_HASH_LENGTH), urllib.parse.urlparse(urow['avatar']).path)) jpg_avatar_url = urow['avatar'] resp = await self.fetch(jpg_avatar_url, method="GET", headers={ 'If-None-Match': last_etag, 'If-Modified-Since': last_modified }) self.assertResponseCodeEqual(resp, 200) # it's impossible to compare the jpegs after being saved a 2nd time # so i simply make sure the value isn't the same as the png self.assertNotEqual(resp.body, png) # check for 304 when trying with new values # NOTE (TODO): moto_server doesn't return 304, but s3 itself does # resp304 = await self.fetch(jpg_avatar_url, method="GET", headers={ # 'If-None-Match': resp.headers['Etag'], # 'If-Modified-Since': resp.headers['Last-Modified'] # }) # self.assertResponseCodeEqual(resp304, 304) # check that avatar stays after other update presp = await self.fetch_signed("/user", signing_key=TEST_PRIVATE_KEY, method="PUT", body={ "username": "******", "name": "Jamie" }) self.assertResponseCodeEqual(presp, 200) data = json_decode(presp.body) self.assertEqual(data['avatar'], jpg_avatar_url) # make sure the original url is still available resp = await self.fetch(first_avatar_url, method="GET") self.assertResponseCodeEqual(resp, 200) self.assertEqual(resp.body, png) async with self.boto: objs = await self.boto.list_objects() self.assertIn('Contents', objs) self.assertEqual(len(objs['Contents']), 2)
async def test_token_balances(self): image = blockies.create(TEST_ADDRESS, size=8, scale=12) hasher = hashlib.md5() hasher.update(image) hash = hasher.hexdigest() url = 'https://toshi.org/sometoken.png' async with self.pool.acquire() as con: await con.execute( "INSERT INTO tokens " "(contract_address, symbol, name, decimals, icon, hash, format) " "VALUES ($1, $2, $3, $4, $5, $6, $7)", "0x1111111111111111111111111111111111111111", "ABC", "Awesome Balls Currency Token", 18, image, hash, 'png') await con.execute( "INSERT INTO tokens " "(contract_address, symbol, name, decimals, icon_url) " "VALUES ($1, $2, $3, $4, $5)", "0x2222222222222222222222222222222222222222", "YAC", "Yet Another Currency Token", 2, url) await con.executemany( "INSERT INTO token_balances " "(contract_address, eth_address, balance) " "VALUES ($1, $2, $3)", [("0x1111111111111111111111111111111111111111", TEST_ADDRESS, hex(2 * 10**18)), ("0x2222222222222222222222222222222222222222", TEST_ADDRESS, hex(10**18))]) await con.executemany( "INSERT INTO token_registrations " "(eth_address) VALUES ($1)", [(TEST_ADDRESS, ), (TEST_ADDRESS_2, )]) resp = await self.fetch("/tokens/{}".format(TEST_ADDRESS), method="GET") self.assertResponseCodeEqual(resp, 200) body = json_decode(resp.body) self.assertEqual(len(body['tokens']), 2) for token in body['tokens']: # check single token balance endpoint resp = await self.fetch("/tokens/{}/{}".format( TEST_ADDRESS, token['contract_address'])) self.assertResponseCodeEqual(resp, 200) single = json_decode(resp.body) icon_url = token['icon'] if token['symbol'] == "YAC": self.assertEqual(single['value'], hex(10**18)) self.assertEqual(token['value'], hex(10**18)) self.assertEqual(icon_url, url) else: self.assertEqual(single['value'], hex(2 * 10**18)) self.assertEqual(token['value'], hex(2 * 10**18)) self.assertEqual( self.get_url("/token/{}.png".format( token['contract_address'])), icon_url) resp = await self.fetch(icon_url, method="GET") self.assertResponseCodeEqual(resp, 200) self.assertEqual(resp.headers.get('Content-Type'), 'image/png') self.assertEqual(resp.body, image) # make sure single token balance is 0 for other addresses resp = await self.fetch("/tokens/{}/{}".format( TEST_ADDRESS_2, "0x1111111111111111111111111111111111111111")) self.assertResponseCodeEqual(resp, 200) body = json_decode(resp.body) self.assertEqual(body['value'], "0x0") # make sure single token balance for non-existent token 404s resp = await self.fetch("/tokens/{}/{}".format( TEST_ADDRESS_2, "0x3333333333333333333333333333333333333333")) self.assertResponseCodeEqual(resp, 404)
async def test_update_user_avatar(self): capitalised = 'BobSmith' async with self.pool.acquire() as con: await con.execute("INSERT INTO users (username, token_id) VALUES ($1, $2)", capitalised, TEST_ADDRESS) boundary = uuid4().hex headers = {'Content-Type': 'multipart/form-data; boundary={}'.format(boundary)} png = blockies.create(TEST_PAYMENT_ADDRESS, size=8, scale=12, format='PNG') files = [('image.png', png)] body = body_producer(boundary, files) resp = await self.fetch_signed("/user", signing_key=TEST_PRIVATE_KEY, method="PUT", body=body, headers=headers) self.assertResponseCodeEqual(resp, 200) async with self.pool.acquire() as con: arow = await con.fetchrow("SELECT * FROM avatars WHERE token_id = $1", TEST_ADDRESS) urow = await con.fetchrow("SELECT * FROM users WHERE token_id = $1", TEST_ADDRESS) self.assertIsNotNone(arow) self.assertEqual(arow['img'], files[0][1]) self.assertIsNotNone(urow) self.assertIsNotNone(urow['avatar']) self.assertEqual(urow['avatar'], "/avatar/{}.png".format(TEST_ADDRESS)) resp = await self.fetch("/avatar/{}.png".format(TEST_ADDRESS), method="GET") self.assertResponseCodeEqual(resp, 200) # easy to test png, it doesn't change so easily when "double" saved self.assertEqual(resp.body, png) self.assertIn('Etag', resp.headers) last_etag = resp.headers['Etag'] self.assertIn('Last-Modified', resp.headers) last_modified = resp.headers['Last-Modified'] # try update with jpeg jpeg = blockies.create(TEST_ADDRESS_2, size=8, scale=12, format='JPEG') # rotate jpeg # TODO: figure out if there's actually a way to test that # this is working as expected jpeg = Image.open(BytesIO(jpeg)).rotate(90) stream = BytesIO() # generate exif info for rotation exif_dict = {"0th": { piexif.ImageIFD.XResolution: (jpeg.size[0], 1), piexif.ImageIFD.YResolution: (jpeg.size[1], 1), piexif.ImageIFD.Orientation: 8 }} jpeg.save(stream, format="JPEG", exif=piexif.dump(exif_dict)) jpeg = stream.getbuffer().tobytes() files = [('image.jpg', jpeg)] body = body_producer(boundary, files) resp = await self.fetch_signed("/user", signing_key=TEST_PRIVATE_KEY, method="PUT", body=body, headers=headers) self.assertResponseCodeEqual(resp, 200) resp = await self.fetch("/avatar/{}.jpg".format(TEST_ADDRESS), method="GET", headers={ 'If-None-Match': last_etag, 'If-Modified-Since': last_modified }) self.assertResponseCodeEqual(resp, 200) # it's impossible to compare the jpegs after being saved a 2nd time # so i simply make sure the value isn't the same as the png self.assertNotEqual(resp.body, png) # check for 304 when trying with new values resp304 = await self.fetch("/avatar/{}.jpg".format(TEST_ADDRESS), method="GET", headers={ 'If-None-Match': resp.headers['Etag'], 'If-Modified-Since': resp.headers['Last-Modified'] }) self.assertResponseCodeEqual(resp304, 304) # check that avatar stays after other update presp = await self.fetch_signed("/user", signing_key=TEST_PRIVATE_KEY, method="PUT", body={ "username": "******", "name": "Jamie" }) self.assertResponseCodeEqual(presp, 200) data = json_decode(presp.body) self.assertTrue(data['avatar'].endswith("/avatar/{}.jpg".format(TEST_ADDRESS))) # make sure png 404's now resp = await self.fetch("/avatar/{}.png".format(TEST_ADDRESS), method="GET", headers={ 'If-None-Match': resp.headers['Etag'], 'If-Modified-Since': resp.headers['Last-Modified'] }) self.assertResponseCodeEqual(resp, 404)
import blockies data = blockies.create('moonero1') name = 'moonero1.png' with open(name, 'wb') as png: png.write(data) data = blockies.create('moonero2') name = 'moonero2.png' with open(name, 'wb') as png: png.write(data) data = blockies.create('moonero3') name = 'moonero3.png' with open(name, 'wb') as png: png.write(data) data = blockies.create('moonero4') name = 'moonero4.png' with open(name, 'wb') as png: png.write(data) data = blockies.create('moonero5') name = 'moonero5.png' with open(name, 'wb') as png: png.write(data) data = blockies.create('moonero6') name = 'moonero6.png' with open(name, 'wb') as png: png.write(data)