Here is how this is done in PyObjC, which has been tested as an Automator {Service, Application} on OS X 10.9.5, and 10.10.3. It makes assumptions about the location of the jpg folder A, and the raw folder B, but none about the destination folder, as this is chosen via an AppleScript choose folder dialog from the script. It does not assume all jpg are lowercase extensions. It does assume that all raw extensions are upper-case CR2. When processing is complete, it drops down a user notification panel with a count of the files moved to the destination folder.
As the Script is self-contained, it only requires a Run Shell Script Automator action, from the Utilities Library, added to the Workflow. For the shell, one choses Python instead of the default Bash. If it is to be a Service, then it receives no input from any application. If an Application, pass input can be ignored, as the application is not looking for Automator input. Select all of the Python boilerplate, and remove it. Copy/paste the following Python script into this Run Shell Script window, and then Automator > Save… to your Desktop (if application) and give it a meaningful name. Double-click to launch folder chooser.
Code
#!/usr/bin/python
# -*- coding: utf-8 -*-
'''
A Python/Objective-C application that prompts for a user-specified
destination folder, matches a folder of jpg files to their name
equivalence in another folder containing raw cr2 image files, and
finally moves the matched raw files into the destination folder.
'''
from Foundation import (
NSAppleScript,
NSUserNotification,
NSUserNotificationCenter
)
import shutil
import locale
import os
import sys
folder_a = os.path.expanduser('~/Pictures/folderA')
folder_b = os.path.expanduser('~/Pictures/folderB')
valid_extension = ['.jpg', '.JPG', '.cr2', '.CR2']
match_index = []
raw_ext = '.CR2'
title = 'Raw File Processing Facility'
as_str = '''
property defloc : path to pictures folder
try
tell application "Finder"
activate
set destFolder to POSIX path of (choose folder default location defloc invisibles no)
end tell
on error msg number enbr
return "None"
end try'''
def is_image_file(filename, extensions=valid_extension):
''' return filename only on valid extension '''
return any(filename.endswith(e) for e in extensions)
def notify(title, subtitle, text):
''' User Notification panel '''
notification = NSUserNotification.alloc().init()
notification.setTitle_(str(title))
notification.setSubtitle_(str(subtitle))
notification.setInformativeText_(str(text))
# notification.setSoundName_("NSUserNotificationDefaultSoundName")
(NSUserNotificationCenter.defaultUserNotificationCenter().
scheduleNotification_(notification))
def main():
# Prompt for user-specified destination folder
t = NSAppleScript.alloc().initWithSource_(as_str)
result = t.executeAndReturnError_(None)
dest_folder = result[0].stringValue().encode('utf-8')
# user clicked Cancel, did not choose a folder, or AppleScript error
if ('None' in dest_folder
or dest_folder == os.path.expanduser('~/Pictures/')):
s = 'Bad user input'
m = 'No files processed.'
notify(title, s, m)
sys.exit(1)
# Strip extension from all valid jpg and replace with CR2 for indexing.
for name in filter(is_image_file, os.listdir(folder_a)):
match_index.append(os.path.splitext(name)[0] + raw_ext)
# Get a list of all raw (CR2) files.
raw_files = os.listdir(folder_b)
# Match jpg to cr2 and build move list
move_files = list(set(match_index).intersection(raw_files))
# Move the files to destination. Behaves like UNIX mv command.
for name in move_files[:]:
(shutil.move(os.path.join(folder_b, name),
os.path.join(dest_folder, name)))
locale.setlocale(locale.LC_ALL, '')
# handle number punctuation automatically by default locale
s = 'Processing Complete'
m = "{:n}".format(len(move_files)) + ' files moved.'
notify(title, s, m)
if __name__ == '__main__':
sys.exit(main())