text: import os
  import argparse
  from PIL import Image, ExifTags, IptcImagePlugin
  from fractions import Fraction
  from datetime import datetime
  from GPSPhoto import gpsphoto
  
  if __name__ == "__main__":
  	parser = argparse.ArgumentParser()
  	parser.add_argument('-n', '--name', dest='gallery_name', required=True, help='Gallery directory name')
  	parser.add_argument('-p', '--preview', dest='preview', default=1, help='Image number of preview photo')
  	parser.add_argument('-t', '--title', dest='title', help='Gallery title')
  	parser.add_argument('-d', '--date', dest='date', help='Gallery shooting date')
  	parser.add_argument('-z', '--zfill', dest='zfill', default=4, help='Number of total figures in files names')
  	parser.add_argument('-x', '--suffix', dest='suffix', default="jpg", help="Files suffix")
  	parser.add_argument('-ts', '--thumbnail-size', dest='thumbnail_size', default='600,400', help="Width and height of thumbnails")
  	parser.add_argument('-st', '--skip-thumbs', dest='skip_thumbnails', default=False, action='store_true', help="Don't create thumbnails (assume they already exist)")
  	parser.add_argument('-so', '--skip-overview', dest='skip_overview', default=False, action='store_true', help="Don't add gallery to overview.yml")
  	parser.add_argument('-sg', '--skip-gallery', dest='skip_gallery', default=False, action='store_true', help="Don't add gallery md file")
  	parser.add_argument('-he', '--hide-exif', dest='hide_exif', default=False, action='store_true', help="Do not show EXIF metadata")
  	args = parser.parse_args()
  
  	photos_path = os.getcwd() + "/assets/photography/" + args.gallery_name
  	photos = [name for name in os.listdir(photos_path) if os.path.isfile(os.path.join(photos_path, name)) and name.endswith(args.suffix) and 'thumbnail' not in name]
  	num_of_photos = len(photos)
  	prefix = photos[0].split('-', 1)[0]
  
  	def get_gps_location(filename, gps_info):
  		try:
  			gps = gpsphoto.getGPSData(filename)
  			if all(k in gps.keys() for k in ['Latitude', 'Longitude']):
  				return f"{gps['Latitude']},{gps['Longitude']}"
  			else:
  				return None
  		except:  # Pillow==8.3.1
  			if not isinstance(gps_info, dict) or len(gps_info.keys()) < 4:
  				return None
  			v = list()
  			for i in [2, 4]:
  				v.append(f'{int(gps_info[i][0])}°{gps_info[i][1]}{gps_info[i - 1]}')
  			return ','.join(v)
  
  	def get_varing_attribute(exif_info, att_name):
  		raw_att = exif_info[att_name] if att_name in exif_info else None
  		if hasattr(raw_att, "__getitem__"):
  			if raw_att[1] == 1 or len(raw_att) == 1:
  				return str(raw_att[0])
  			else:
  				return f"{raw_att[0]}/{raw_att[1]}"
  		elif raw_att is not None:
  			att = float(raw_att)
  			if att < 1.:
  				frac = Fraction(att).limit_denominator()
  				if frac.numerator == 1:
  					return str(frac)
  				else:
  					return str(att)
  			else: 
  				return raw_att
  		else:  # None
  			return '?'
  
  	def is_hdr_from_iptc(im):
  		hdr_iptc_tag = (2, 20)  # IPTC Supplemental Category
  		iptc = IptcImagePlugin.getiptcinfo(im)
  		if iptc is not None and hdr_iptc_tag in iptc:
  			v = iptc.get(hdr_iptc_tag).decode()
  			return 'HDR' in v.upper()
  		else:
  			return False
  
  	def get_image_name_from_id(n):
  		return f'{prefix}-{str(n).zfill(args.zfill)}'
  
  	def get_image_thumbnail_name(name):
  		return f'{name}-thumbnail.{args.suffix}'
  
  	if not args.skip_thumbnails:
  		th_width, th_height = [int(i) for i in args.thumbnail_size.split(',')]
  		for file_name in photos:
  			photo = file_name[:-(len(args.suffix)+1)]
  			thumbnail_size = (th_width, th_width) if th_width > th_height else (th_height, th_height)
  			thumbnail_filename = get_image_thumbnail_name(photo)
  			im = Image.open(os.path.join(photos_path, file_name))
  			im.thumbnail(thumbnail_size, Image.ANTIALIAS)
  			im.save(os.path.join(photos_path, thumbnail_filename))
  
  	min_date = None
  	max_date = None
  	with open(os.getcwd() + f'/_data/galleries/{args.gallery_name}.yml', 'w+') as f:
  		f.write(f'picture_path: {args.gallery_name} \n')
  		f.write('pictures: \n')
  		for i in range(1, num_of_photos+1):
  			photo = get_image_name_from_id(i)
  			photo_path = os.path.join(photos_path, f'{photo}.{args.suffix}')
  			f.write(f'- filename: {photo} \n')
  			f.write(f'  original: {photo}.{args.suffix} \n')
  			f.write(f'  thumbnail: {get_image_thumbnail_name(photo)} \n')
  			f.write('  exif: \n')
  			im = Image.open(photo_path)
  			exif = dict()
  			exif_info = {ExifTags.TAGS[k]: v for k, v in im._getexif().items() if k in ExifTags.TAGS}
  			exif['model'] = exif_info.get('Model', '?')
  			exif['lens'] = exif_info.get('LensModel', None)
  			exif['aperture'] = get_varing_attribute(exif_info, 'FNumber')
  			exif['shutter'] = get_varing_attribute(exif_info, 'ExposureTime')
  			exif['focal'] = get_varing_attribute(exif_info, 'FocalLength') 
  			exif['iso'] = exif_info.get('ISOSpeedRatings', '?')
  			exif['datetime'] = exif_info.get('DateTimeOriginal', '?')
  			exif['gps'] = get_gps_location(photo_path, exif_info.get('GPSInfo', '?'))
  			if is_hdr_from_iptc(im):
  				exif['hdr'] = 'true'
  			for k,v in exif.items():
  				if v is not None:
  					f.write(f'    {k}: {v} \n')
  			if args.hide_exif:
  				f.write(f'    hide_exif: true \n')
  			if exif['datetime']:
  				dt = datetime.strptime(exif['datetime'], '%Y:%m:%d %H:%M:%S').date()
  				if min_date is None: min_date = dt
  				elif min_date > dt: min_date = dt
  				if max_date is None: max_date = dt
  				elif max_date < dt: max_date = dt
  
  	date = ''
  	if args.date:
  		date = args.date
  	else:
  		if min_date is None or max_date is None:
  			pass
  		elif min_date == max_date:
  			date = max_date.strftime("%d/%m/%Y")
  		elif min_date.month == max_date.month and min_date.year == max_date.year:
  			date = f"{min_date.strftime('%d')}-{max_date.strftime('%d/%m/%Y')}"
  		else:
  			date = f"{min_date.strftime('%d/%m/%Y')} - {max_date.strftime('%d/%m/%Y')}"
  	date = date or 'Who knows when...'
  
  	if not args.skip_overview:
  		with open(os.getcwd() + '/_data/galleries/overview.yml', 'r+') as f:
  			photo = get_image_name_from_id(args.preview)
  			content = f.read()
  			f.seek(0, 0)
  			f.write('- \n')
  			f.write(f' title: {args.title or args.gallery_name} \n')
  			f.write(f' directory: {args.gallery_name} \n')
  			f.write(f' date: {date} \n')
  			f.write(' preview: \n')
  			f.write(f'  filename: {photo} \n')
  			f.write(f'  original: {photo}.{args.suffix} \n')
  			f.write(f'  thumbnail: {get_image_thumbnail_name(photo)} \n')
  			f.write(content)
  
  	if not args.skip_gallery:
  		with open(os.getcwd() + f'/galleries/{args.gallery_name}.md', 'w+') as f:
  			f.write('--- \n')
  			f.write('layout: gallery \n')
  			f.write(f'title: {args.title or args.gallery_name} \n')
  			f.write(f'date: {date} \n')
  			f.write('no_menu_item: true \n') 
  			f.write('support: [jquery, gallery] \n')
  			f.write('--- \n\n\n')
  			f.write('<div class="hebrew-col" markdown="1">\n\n\n\n</div>\n\n')
  			f.write('<div class="english-col" markdown="1">\n\n\n\n</div>\n\n')
  			f.write('<div class="end-lang-cols"></div>\n')
  			f.write('{% include gallery-layout.html gallery=site.data.galleries.' + args.gallery_name + ' %} \n')
  