Skip to content

Instantly share code, notes, and snippets.

@djdarcy
Last active February 13, 2024 06:38
Show Gist options
  • Select an option

  • Save djdarcy/5dbb129071f01041ace5e8abf1980baf to your computer and use it in GitHub Desktop.

Select an option

Save djdarcy/5dbb129071f01041ace5e8abf1980baf to your computer and use it in GitHub Desktop.
Python wrapper for ExifTool that allows users to edit social media URLs in image metadata and can show the XMP/exif details of the image
%Image::ExifTool::UserDefined = (
'Image::ExifTool::XMP::Main' => {
socialMedia => { # This is the namespace prefix
SubDirectory => {
TagTable => 'Image::ExifTool::UserDefined::socialMedia'
},
},
},
);
%Image::ExifTool::UserDefined::socialMedia = (
GROUPS => { 0 => 'XMP', 1 => 'XMP-socialMedia', 2 => 'Image' },
NAMESPACE => { socialMedia => 'http://ns.example.com/socialMedia/' },
WRITABLE => 'string', # Making the tags writable as strings
CreatorURL => { },
PurchaseURL => { },
URLInstagram => { },
URLTwitter => { },
URLFacebook => { },
URLPatreon => { },
URLEtsy => { },
URLDeviantArt => { },
URLScribd => { },
URLDocdroid => { },
URLDiscord => { },
URLTapatalk => { },
URLLinkedIn => { },
URLYouTube => { },
URLVimeo => { },
URLSoundCloud => { },
URLSpotify => { },
URLBandcamp => { },
URLTwitch => { },
URLTikTok => { },
URLReddit => { },
URLPinterest => { },
URLBehance => { },
URLFlickr => { },
URLTumblr => { },
URLGitHub => { },
URLMedium => { },
URLTelegram => { },
URLWhatsApp => { },
);
1; # Needed to ensure the config file is properly read
#Created by Dustin Darcy (http://github.com/djdarcy)
#Notes: https://exiftool.org/forum/index.php?topic=15169.0
import argparse
import subprocess
import os
def find_exiftool():
# Get the directory of the current script
script_dir = os.path.dirname(os.path.abspath(__file__))
exiftool_path = os.path.join(script_dir, 'exiftool.exe')
# Check if exiftool.exe is in the same directory as the script
if os.path.isfile(exiftool_path):
return exiftool_path
else:
# Fallback to 'exiftool' assuming it is in the system PATH
return 'exiftool'
# Function to run ExifTool command
def run_exiftool_command(cmd):
subprocess.run(cmd, text=True)
# Define the parser
parser = argparse.ArgumentParser(description='Edit social media URLs in image metadata.')
parser.add_argument('image', help='Path to the image file.')
parser.add_argument('-s', '--show', action='store_true', help='Show the XMP/exif details of the image.')
parser.add_argument('-cfg', '--config', default='customtags.cfg', help='Path to the custom ExifTool config file.')
parser.add_argument('-cr', '--creator', help="URL to creator's information")
parser.add_argument('-pu', '--purchase', help="URL to purchase the item")
parser.add_argument('-tw', '--twitter', help="Twitter profile URL")
parser.add_argument('-ig', '--instagram', help="Instagram profile URL")
parser.add_argument('-pa', '--patreon', help="Patreon profile URL")
parser.add_argument('-et', '--etsy', help="Etsy shop URL")
parser.add_argument('-da', '--deviantart', help="DeviantArt profile URL")
parser.add_argument('-tp', '--tapatalk', help="Tapatalk profile URL")
parser.add_argument('-fb', '--facebook', help="Facebook profile URL")
parser.add_argument('-sc', '--scribd', help="Scribd profile URL")
parser.add_argument('-dd', '--docdroid', help="Docdroid document URL")
parser.add_argument('-di', '--discord', help="Discord invite URL")
parser.add_argument('-li', '--linkedin', help="LinkedIn profile URL")
parser.add_argument('-yt', '--youtube', help="YouTube channel URL")
parser.add_argument('-vm', '--vimeo', help="Vimeo profile URL")
parser.add_argument('-sd', '--soundcloud', help="SoundCloud profile URL")
parser.add_argument('-sp', '--spotify', help="Spotify artist profile URL")
parser.add_argument('-bc', '--bandcamp', help="Bandcamp artist profile URL")
parser.add_argument('-tc', '--twitch', help="Twitch channel URL")
parser.add_argument('-tk', '--tiktok', help="TikTok profile URL")
parser.add_argument('-rd', '--reddit', help="Reddit profile or subreddit URL")
parser.add_argument('-pt', '--pinterest', help="Pinterest profile URL")
parser.add_argument('-bh', '--behance', help="Behance profile URL")
parser.add_argument('-fl', '--flickr', help="Flickr profile URL")
parser.add_argument('-tu', '--tumblr', help="Tumblr blog URL")
parser.add_argument('-gh', '--github', help="GitHub profile URL")
parser.add_argument('-md', '--medium', help="Medium profile URL")
parser.add_argument('-tg', '--telegram', help="Telegram contact or channel URL")
parser.add_argument('-wa', '--whatsapp', help="WhatsApp contact URL")
args = parser.parse_args()
# Use the find_exiftool function to set the correct ExifTool path
exiftool_cmd = find_exiftool()
# Build the ExifTool command
orig_cmd = [exiftool_cmd, '-config', args.config]
cmd = orig_cmd.copy()
# Add tags to the command
if args.creator:
cmd.append(f'-XMP-socialMedia:CreatorURL={args.creator}')
if args.purchase:
cmd.append(f'-XMP-socialMedia:PurchaseURL={args.purchase}')
if args.instagram:
cmd.append(f'-XMP-socialMedia:URLInstagram={args.instagram}')
if args.twitter:
cmd.append(f'-XMP-socialMedia:URLTwitter={args.twitter}')
if args.facebook:
cmd.append(f'-XMP-socialMedia:URLFacebook={args.facebook}')
if args.patreon:
cmd.append(f'-XMP-socialMedia:URLPatreon={args.patreon}')
if args.etsy:
cmd.append(f'-XMP-socialMedia:URLEtsy={args.etsy}')
if args.deviantart:
cmd.append(f'-XMP-socialMedia:URLDeviantArt={args.deviantart}')
if args.scribd:
cmd.append(f'-XMP-socialMedia:URLScribd={args.scribd}')
if args.docdroid:
cmd.append(f'-XMP-socialMedia:URLDocdroid={args.docdroid}')
if args.discord:
cmd.append(f'-XMP-socialMedia:URLDiscord={args.discord}')
if args.tapatalk:
cmd.append(f'-XMP-socialMedia:URLTapatalk={args.tapatalk}')
if args.linkedin:
cmd.append(f'-XMP-socialMedia:URLLinkedIn={args.linkedin}')
if args.youtube:
cmd.append(f'-XMP-socialMedia:URLYouTube={args.youtube}')
if args.vimeo:
cmd.append(f'-XMP-socialMedia:URLVimeo={args.vimeo}')
if args.soundcloud:
cmd.append(f'-XMP-socialMedia:URLSoundCloud={args.soundcloud}')
if args.spotify:
cmd.append(f'-XMP-socialMedia:URLSpotify={args.spotify}')
if args.bandcamp:
cmd.append(f'-XMP-socialMedia:URLBandcamp={args.bandcamp}')
if args.twitch:
cmd.append(f'-XMP-socialMedia:URLTwitch={args.twitch}')
if args.tiktok:
cmd.append(f'-XMP-socialMedia:URLTikTok={args.tiktok}')
if args.reddit:
cmd.append(f'-XMP-socialMedia:URLReddit={args.reddit}')
if args.pinterest:
cmd.append(f'-XMP-socialMedia:URLPinterest={args.pinterest}')
if args.behance:
cmd.append(f'-XMP-socialMedia:URLBehance={args.behance}')
if args.flickr:
cmd.append(f'-XMP-socialMedia:URLFlickr={args.flickr}')
if args.tumblr:
cmd.append(f'-XMP-socialMedia:URLTumblr={args.tumblr}')
if args.github:
cmd.append(f'-XMP-socialMedia:URLGitHub={args.github}')
if args.medium:
cmd.append(f'-XMP-socialMedia:URLMedium={args.medium}')
if args.telegram:
cmd.append(f'-XMP-socialMedia:URLTelegram={args.telegram}')
if args.whatsapp:
cmd.append(f'-XMP-socialMedia:URLWhatsApp={args.whatsapp}')
# Run the ExifTool command to edit the image?
if(cmd != orig_cmd):
cmd.append(args.image)
run_exiftool_command(cmd)
# Last possibility: Show the XMP/exif details of the image
if args.show:
run_exiftool_command([exiftool_cmd, args.image])
@echo off
setlocal
:: Get the full path of the directory where the batch script resides
set "script_dir=%~dp0"
:: Check for image file argument
if "%~1"=="" (
echo Usage: update_metadata.cmd ^<image_file^>
exit /b 1
)
:: Set the predefined social media links
set "creator_url=https://linktr.ee/..."
set "purchase_url=https://www.etsy.com/listing/.../..."
set "instagram=https://www.instagram.com/.../"
set "twitter=https://x.com/..."
set "patreon=http://patreon.com/..."
set "etsy=https://www.etsy.com/shop/..."
set "deviantart=https://www.deviantart.com/.../"
set "docdroid=https://www.docdroid.net/rors5BX/2009-the-scarcity-hypothesis-sh-dustin-darcy-pdf"
:: Call the Python script with all the arguments, using the full path
python "%script_dir%exiftool.py" "%~1" ^
-cr "%creator_url%" ^
-pu "%purchase_url%" ^
-ig "%instagram%" ^
-tw "%twitter%" ^
-pa "%patreon%" ^
-et "%etsy%" ^
-da "%deviantart%" ^
-dd "%docdroid%" ^
-s
endlocal
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment