Best Python code snippet using localstack_python
shopkeeper.py
Source:shopkeeper.py  
1#!/usr/bin/python2# imported modules3from PIL import Image, ImageDraw, ImageFont, ImageOps4import json5import re6import requests7import sys8# configuration constants9BUILD_IMAGE_DIMENSIONS = (1920, 1080)10BACKGROUND_ALPHA = 5511DRAW_COLOR = (50, 50, 50)12BACK_COLOR = (0, 0, 0)13TEXT_COLOR = (100, 100, 100)14TRANSPARENCY_THRESHOLD = 6415LETTER_OPTIONS = ('Q', 'W', 'E', 'R')16ABILITY_IMAGE_CHARACTER = '@' # a character that wouldn't normally show up in the ability order17FONT_SIZES = {18	'H1': 48,19	'H2': 40,20	'H3': 32,21	'H4': 2422}23FONT_HEIGHT_BONUS = 2 # the font is usually drawn a few pixels short of its supposed height24FONT_FILEPATH = '../shared/CarroisGothicSC-Regular.ttf'25WIKI_BASE_URL = 'https://leagueoflegends.fandom.com/wiki'26WIKI_IMAGE_URL_PATTERN = r'https://static\.wikia\.nocookie\.net/leagueoflegends/images/.+?\.(?:jpg|png)'27ENCHANTABLE_ITEMS = ['Stalker\'s Blade', 'Skirmisher\'s Sabre', 'Pridestalker\'s Blade', 'Tracker\'s Knife',  'Ranger\'s Trailblazer',  'Poacher\'s Knife']28# main: loads the given data from sys_argv and runs each draw function in succession to get the final image29def main(sys_argv):30	if len(sys_argv) < 2:31		print('Error: no input file given.')32		sys.exit(1)33	elif not sys_argv[1].endswith('.json'):34		print('Error: argument must be a .json file.')35		sys.exit(1)36	# we're gonna put the output image in the same location as the input json, just with a different extension37	input_filepath = sys_argv[1]38	output_filepath = re.sub(r'\.json$', '.png', input_filepath)39	with open(input_filepath) as input_filehandle:40		build_data = json.load(input_filehandle)41	# the base image is pure black, then we draw each layer on top of it42	build_image = Image.new('RGB', BUILD_IMAGE_DIMENSIONS, (0, 0, 0))43	for draw_function in (draw_background, draw_metadata, draw_summoner_spells, draw_runes, draw_abilities, draw_items):44		build_image = draw_function(build_image, build_data)45		print("Finished step: " + draw_function.__name__)46	if build_image:47		build_image.save(output_filepath)48		print('Success: created "%s" from "%s".' % (output_filepath, input_filepath))49		sys.exit(0)50	else:51		print('Error: something went wrong while creating the build image. Perhaps malformed data?')52		sys.exit(1)53# draw_background: gets the skin image for the loaded build_data and draws it on build_image as the background54def draw_background(build_image, build_data):55	skin_images = get_images(56		'/'.join((WIKI_BASE_URL, build_data.get('Champion'), 'Skins')),57		re.compile(r'data-skin="(.*?)"><a href="(%s)' % WIKI_IMAGE_URL_PATTERN)58	)59	skin_image = skin_images.get(build_data.get('Skin').replace('\'', '''))60	if skin_image:61		# scale the skin image to fit the width of the build image62		image_width, image_height = skin_image.size63		scale_ratio = float(BUILD_IMAGE_DIMENSIONS[0]) / image_width64		skin_image = skin_image.resize((int(image_width * scale_ratio), int(image_height * scale_ratio)))65		# then center and crop the skin image to fit the height of the build image66		image_width, image_height = skin_image.size67		height_difference = image_height - BUILD_IMAGE_DIMENSIONS[1]68		top_cut = height_difference / 269		bottom_cut = height_difference - top_cut70		skin_image = skin_image.crop((0, top_cut, BUILD_IMAGE_DIMENSIONS[0], image_height - bottom_cut))71		# make it mostly transparent so it's not a distracting background72		skin_image.putalpha(BACKGROUND_ALPHA)73		build_image.paste(skin_image, (0, 0), skin_image)74	return build_image75# draw_metadata: loads the metadata text from build_data and draws them on build_image in the corners76def draw_metadata(build_image, build_data):77	# load our font in all of the sizes we need for the metadata78	scaled_fonts = {}79	for header_level, font_size in FONT_SIZES.items():80		scaled_fonts[header_level] = ImageFont.truetype(FONT_FILEPATH, font_size)81	metadata_drawer = ImageDraw.Draw(build_image)82	# draw each of the pieces offset from the specified corner83	for text_anchor, text_offset, metadata_type, header_level in [84		(('left' , 'top'   ), (32, 32), 'Champion', 'H1'),85		(('left' , 'top'   ), (32, 88), 'Role'    , 'H2'),86		(('right', 'bottom'), (32, 32), 'Skin'    , 'H2'),87		(('right', 'bottom'), (32, 80), 'Chroma'  , 'H3'),88		(('left' , 'bottom'), (32, 32), 'Creator' , 'H4'),89		(('right', 'top'   ), (32, 32), 'Patch'   , 'H4'),90	]:91		metadata_text = build_data.get(metadata_type)92		if not metadata_text:93			continue94		scaled_font = scaled_fonts[header_level]95		text_width, text_height = metadata_drawer.textsize(metadata_text, scaled_font)96		text_position = (97			0 + text_offset[0] if text_anchor[0] == 'left' else BUILD_IMAGE_DIMENSIONS[0] - (text_offset[0] + text_width ),98			0 + text_offset[1] if text_anchor[1] == 'top'  else BUILD_IMAGE_DIMENSIONS[1] - (text_offset[1] + text_height)99		)100		metadata_drawer.text(text_position, metadata_text, TEXT_COLOR, scaled_font)101	return build_image102# draw_summoner_spells: gets the summoner spell images for the loaded build_data and draws them on build_image side by side103def draw_summoner_spells(build_image, build_data):104	spell_images = get_images(105		'/'.join((WIKI_BASE_URL, 'Summoner_spell')),106		re.compile(r'<div class="grid-image label-after spell-icon" data-param="(\w+).*?data-src="(%s)' % WIKI_IMAGE_URL_PATTERN, re.DOTALL)107	)108	x_offset, y_offset = 128, 256109	for spell_name in build_data.get('Summoner Spells'):110		spell_image = spell_images.get(spell_name)111		if spell_image:112			build_image.paste(ImageOps.expand(spell_image, 1, DRAW_COLOR), (x_offset, y_offset))113			x_offset += 160114	return build_image115# draw_runes: gets the rune images for the loaded build_data and draws them on build_image in two columns, keystone/primary and secondary/shards116def draw_runes(build_image, build_data):117	path_images = get_images(118		'/'.join((WIKI_BASE_URL, 'Rune')),119		re.compile(r'<li><img alt="(\w+) icon.png".*?data-src="(%s)' % WIKI_IMAGE_URL_PATTERN),120		False121	)122	keystone_images = get_images(123		'/'.join((WIKI_BASE_URL, 'Rune')),124		re.compile(r'title="([\w :;&#]+)".*?data-src="(%s/revision/latest/scale-to-width-down/52)' % WIKI_IMAGE_URL_PATTERN),125		False,126		{ '52': '112' } # the image is 52px on this page, but we want it at 112px; we can't just use the base link because it's 256px there127	)128	rune_images = get_images(129		'/'.join((WIKI_BASE_URL, 'Rune')),130		re.compile(r'title="([\w :;&#]+)".*?data-src="(%s/revision/latest/scale-to-width-down/52)' % WIKI_IMAGE_URL_PATTERN),131		False,132		{ '52': '64' } # the image is 52px on this page, but we want it at 64px; we can't just use the base link because it's 108px there133	)134	shard_images = get_images(135		'/'.join((WIKI_BASE_URL, 'Rune')),136		re.compile(r'data-image-name="Rune shard ([\w ]+)\.png".*?data-src="(%s/revision/latest/scale-to-width-down/30)' % WIKI_IMAGE_URL_PATTERN),137		False,138		{ '30': '32' } # the image is 30px on this page, but we want it at 32px; we can't just use the base link because it's 35px there139	)140	# path images141	rune_data = build_data.get('Runes')142	x_center_line = 128 + 1 + int(64 / 2)143	x_offset, y_offset = x_center_line - int(85 / 2), 448144	for path_name in rune_data.get('Paths'):145		path_image = path_images.get(path_name.replace('\'', '''))146		if path_image:147			# remove the half-transparent backgrounds of these images148			pixel_array = path_image.load()149			for i in range(path_image.size[0]):150				for j in range(path_image.size[1]):151					if pixel_array[i, j][3] < TRANSPARENCY_THRESHOLD:152						pixel_array[i, j] = (0, 0, 0, 0)153			build_image.paste(path_image, (x_offset, y_offset), path_image)154			x_offset += 160155	# keystone image156	x_offset = x_center_line - int(112 / 2)157	y_offset += 85 + 32158	keystone_name = rune_data.get('Primary')[0] # just get the keystone, we'll do the others below159	keystone_image = keystone_images.get(keystone_name.replace('\'', '''))160	if keystone_image:161		build_image.paste(keystone_image, (x_offset, y_offset), keystone_image)162	# primary images163	x_offset = x_center_line - int(64 / 2)164	y_offset += 112 + int(32 / 2)165	for rune_name in rune_data.get('Primary')[1:]: # skip the keystone, we did that above166		rune_image = rune_images.get(rune_name.replace('\'', '''))167		if rune_image:168			build_image.paste(rune_image, (x_offset, y_offset), rune_image)169			y_offset += 64 + 32170	# secondary images171	x_offset = x_center_line - int(64 / 2) + 160172	y_offset = 448 + 85 + 32 + 112 - 64 - 32173	for rune_name in rune_data.get('Secondary'):174		rune_image = rune_images.get(rune_name.replace('\'', '''))175		if rune_image:176			build_image.paste(rune_image, (x_offset, y_offset), rune_image)177			y_offset += 64 + 32178	# shard images179	x_offset = x_center_line - int(32 / 2) + 160180	y_offset += 16181	for shard_name in rune_data.get('Shards'):182		shard_image = shard_images.get(shard_name.replace('\'', '''))183		if shard_image:184			build_image.paste(shard_image, (x_offset, y_offset), shard_image)185			y_offset += 32 + 32186	return build_image187# draw_abilities: gets the ability images for the loaded build_data and draws them on build_image188# with level numbers and ability letters for each ability listed in the build data's ability order189def draw_abilities(build_image, build_data):190	ability_images = get_images(191		'/'.join((WIKI_BASE_URL, build_data.get('Champion'), 'LoL')),192		re.compile(r'<div class="skill skill_(\w)".*?data-source="primary_icon">\s*?<a href="(%s)' % WIKI_IMAGE_URL_PATTERN, re.DOTALL)193	)194	ability_drawer = ImageDraw.Draw(build_image)195	x_offset, y_offset = BUILD_IMAGE_DIMENSIONS[0] - 96, 96196	ability_order = build_data.get('Abilities')197	ability_level = len(ability_order)198	for ability_letter in reversed(ABILITY_IMAGE_CHARACTER + ability_order):199		if ability_letter != ABILITY_IMAGE_CHARACTER:200			outline_rectangle = ((x_offset - 65, y_offset), (x_offset, y_offset + 33))201			ability_drawer.rectangle(outline_rectangle, None, DRAW_COLOR)202			build_image = center_text(build_image, outline_rectangle, str(ability_level), 20)203		y_offset += 33204		for letter_option in LETTER_OPTIONS:205			outline_rectangle = ((x_offset - 65, y_offset), (x_offset, y_offset + 65))206			ability_drawer.rectangle(outline_rectangle, None, DRAW_COLOR)207			if ability_letter == ABILITY_IMAGE_CHARACTER:208				build_image.paste(ability_images.get(letter_option.lower()), (x_offset - 65 + 1, y_offset + 1))209			elif ability_letter.upper() == letter_option:210				build_image = center_text(build_image, outline_rectangle, letter_option, 20)211			y_offset += 65212		ability_level -= 1213		x_offset -= 65214		y_offset = 96215	return build_image216# draw_items: gets the item images for the loaded build_data and draws them on build_image split out by section217def draw_items(build_image, build_data):218	item_images = get_images(219		'/'.join((WIKI_BASE_URL, 'Item')),220		re.compile(r'<div class="item-icon".*?data-item="(.*?)".*?src="(%s)' % WIKI_IMAGE_URL_PATTERN, re.DOTALL)221	)222	item_drawer = ImageDraw.Draw(build_image)223	ability_section_end = 97 + 33 + 65 * len(LETTER_OPTIONS) # calculate the bottom of the ability section and go from there224	x_offset, y_offset = BUILD_IMAGE_DIMENSIONS[0] - 96, ability_section_end + 128225	for item_section in reversed(build_data.get('Items')):226		item_options = item_section.get('Options')227		# create sublists so no column is too long228		sublist_limit = 4229		sublist_count = (len(item_options) + sublist_limit - 1) // sublist_limit230		option_lists = [item_options[i * sublist_limit:(i + 1) * sublist_limit] for i in range(sublist_count)]231		# draw each item section label centered below the item images232		block_width = ((sublist_count * 2 - 1) * 65)233		block_height = (4 * 65 + 3 * 33)234		outline_rectangle = ((x_offset - block_width, y_offset + block_height + 33), (x_offset, y_offset + block_height + 49))235		build_image = center_text(build_image, outline_rectangle, item_section.get('Label'), 24)236		for option_list in reversed(option_lists):237			# we want to vertically center any column that doesn't have the full number of items238			y_offset += 49 * (sublist_limit - len(option_list))239			for item_name in option_list:240				outline_rectangle = ((x_offset - 65, y_offset), (x_offset, y_offset + 65))241				item_drawer.rectangle(outline_rectangle, BACK_COLOR, DRAW_COLOR)242				# we have special logic for getting enchantable item images, if they have a valid enchantment specified in parentheses243				item_image = None244				for enchantable_item in ENCHANTABLE_ITEMS:245					if re.search(r'^%s \(.*?\)$' % enchantable_item, item_name):246						enchantment_images = get_images(247							'/'.join((WIKI_BASE_URL, enchantable_item)),248							re.compile(r'<img (?:style="" )?src="(%s).*?".*?alt="(?:[^"]*?\()?(.+?)(?:\)[^"]*?)?"' % WIKI_IMAGE_URL_PATTERN),249							True250						)251						for enchantment_name in enchantment_images.keys():252							if item_name == '%s (%s)' % (enchantable_item, enchantment_name):253								item_image = enchantment_images.get(enchantment_name)254								break255						else:256							# fall back on using the base image if the given enchantment doesn't match any of the ones found257							item_image = item_images.get(enchantable_item.replace('\'', '''))258						break259				# use the base image if there's no enchantment specified260				# which is the most likely option, since only the old jungle items have enchantments261				else:262					item_image = item_images.get(item_name.replace('\'', '''))263				if item_image:264					item_mask = item_image if 'A' in item_image.mode else None265					build_image.paste(item_image, (x_offset - 65 + 1, y_offset + 1), item_mask)266				y_offset += 33 + 65267			x_offset -= 65 + 65268			y_offset = ability_section_end + 128269		x_offset -= 65270	return build_image271# get_images: parses the source of wiki_page for every match to image_regex, creating a mapping of the text in the first272# capture group to the downloaded image located at the url in the second capture group; switches the key and value if273# reverse_order is given, and applies any link_modifiers find:replace pairs to the url before downloading the image274def get_images(wiki_page, image_regex, reverse_order = False, link_modifiers = None):275	page_source = requests.get(wiki_page).text276	image_links = image_regex.findall(page_source) # the regex should parse the page for paired groups in each match277	image_map = {}278	for image_key, image_link in image_links: # each of the pairs should be a link to an image and a way to refer to it (potentially reversed)279		if image_key in image_map:280			continue281		if reverse_order:282			image_key, image_link = image_link, image_key283		if link_modifiers:284			for old_regex, new_string in link_modifiers.items():285				image_link = re.sub(old_regex, new_string, image_link)286		image_map[image_key] = Image.open(requests.get(image_link, stream = True).raw) # we create a mapping of each key to its downloaded image287	return image_map288# center_text: centers draw_text in the outline_rectangle bounding box, drawing it on build_image in size font_size text289def center_text(build_image, outline_rectangle, draw_text, font_size):290	outline_width = outline_rectangle[1][0] - outline_rectangle[0][0]291	outline_height = outline_rectangle[1][1] - outline_rectangle[0][1]292	text_drawer = ImageDraw.Draw(build_image)293	scaled_font = ImageFont.truetype(FONT_FILEPATH, font_size)294	text_width, text_height = text_drawer.textsize(draw_text, scaled_font)295	text_position = (296		outline_rectangle[0][0] + int((outline_width - text_width) / 2),297		outline_rectangle[0][1] + int((outline_height - text_height) / 2) - FONT_HEIGHT_BONUS298	)299	text_drawer.text(text_position, draw_text, TEXT_COLOR, scaled_font)300	return build_image301# standard ifmain with args302if __name__ == '__main__':...run.py
Source:run.py  
...58        docker_utils.rm_container(docker_utils.DockerContainer(build_image))59        docker_utils.rm_image(build_image)60    docker_utils.create_volume(CONFIG['DOCKER']['cache_volume'])61    docker_utils.create_network(CONFIG['DOCKER']['network'])62    build_build_image(args, build_image)63    run_build_image(args, build_image)64    build_main_image(args, main_image)65    create_main_container(args, main_image)66    database.start(migrations=args['--apply-migrations'], start_db=args['--start-db'])67    start_main_container(args)68    docker_utils.export_logs(main_image)69def build_build_image(args: dict, build_image: str = None) -> None:70    """Builds the build image.71    Args:72        args (dict): Parsed command-line arguments passed to the script.73        build_image (str): Optional; Build image name. Defaults to the value from config file.74    """75    build_image = build_image if build_image else CONFIG['DOCKER']['build_image']76    if not args['--rebuild'] and docker_utils.item_exists('image', build_image):77        utils.warn(f"Image '{build_image}' already exists, not building")78        return79    utils.log(f"Building '{build_image}' image")80    build_image_cmd = [81        'docker',82        'build',83        '--tag',84        build_image,85        '--file',86        os.path.join('docker', 'Dockerfile-gradle'),87        '.',88    ]89    if args['--no-cache']:90        build_image_cmd.insert(2, '--no-cache')91    elif args['--cache-from']:92        for item in args['--cache-from']:93            build_image_cmd[2:2] = ['--cache-from', item]94    utils.execute_cmd(build_image_cmd)95def run_build_image(args: dict, build_image: str = None) -> None:96    """Runs the build image and copies the compiled JAR file out of the container.97    Args:98        args (dict): Parsed command-line arguments passed to the script.99        build_image (str): Optional; Build image name. Defaults to the value from config file.100    """101    build_image = build_image if build_image else CONFIG['DOCKER']['build_image']102    build_container = build_image103    if not args['--rebuild'] and docker_utils.item_exists('container', build_container):104        utils.warn(f"Container '{build_container}' already exists, not running")105        return106    utils.log(f"Running '{build_image}' image")107    build_container_cmd = [108        'docker',109        'run',...ci.py
Source:ci.py  
1import os2from invoke import task3from . import util4@task(default=True)5def tag_build(ctx):6    org = current_image = ctx.docker['org']7    for name in ctx.hub['images']:8        current_image = '{}/{}:{}'.format(org, name, util.get_docker_tag_ci())9        build_tag = 'build-' + os.getenv('TRAVIS_BUILD_NUMBER', '0')10        build_image = '{}/{}:{}'.format(org, name, build_tag)11        latest_image = '{}/{}:{}'.format(org, name, 'latest')12        print('tagging {} as {}'.format(current_image, build_image))13        ctx.run('docker tag {} {}'.format(current_image, build_image))14        if os.getenv('TRAVIS_PULL_REQUEST') == 'false':15            print('tagging {} as {}'.format(current_image, latest_image))16            ctx.run('docker tag {} {}'.format(current_image, latest_image))17    #18    # build_image = util.image_name(19    #     ctx, 'build-{}'.format(os.getenv('TRAVIS_BUILD_NUMBER', '0')))20    # latest_image = util.image_name(ctx, 'latest')21    #22    # print('tagging {} as {}'.format(current_image, build_image))23    # ctx.run('docker tag {} {}'.format(current_image, build_image))24    #25    # if os.getenv('TRAVIS_PULL_REQUEST') == 'false':26    #     print('tagging {} as {}'.format(current_image, latest_image))...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
