蛮力肌肉导入
你可能想试试这个硬核脚本。它需要 AGES 才能完成,但它应该可以工作,因为它会按照您的要求执行……它将每个文件一个接一个地添加到指定的项目中,并检查以确保没有任何仅按名称重复的文件。我即将在 13262 张图片上测试这个脚本。它可能会运行一整夜,但它有望击败不断失败的内置导入器。
我建议您在第一次运行时创建一个测试项目,以确保您不会导入重复项。然后,您可以选择将图像移动到 Aperture 中的相应项目中。我已经设置好了。如果您想忽略这一点并将它们直接导入到原始项目中,您可以通过更改以下行来做到这一点:
my importToApertureAsReference(itemAlias, projectDst)
至
my importToApertureAsReference(itemAlias, projectName)
OS X 10.9.4
光圈3.5.1
免责声明:我只是把它放在一起。有改进的余地,比如检查以确保列表中的文件都是图片。我没有做任何这样的检查。这可以在 shell 命令中完成,或者使用系统事件来获取每个文件通过时的类型。此外,当您运行此程序时,您的计算机将翻转。我建议你不要在你的电脑上做任何其他事情。
AppleScript - 将缺失的文件一一导入项目”
通过比较图片的名称和文件的名称
2014 年 8 月 1 日更新
通过让 bourne 脚本完成大部分工作,我显着提高了脚本的速度。AppleScript 在与程序交谈时会陷入困境,但在迭代列表时相对较快。我只是使用了 bourne 脚本的find
命令basename
来创建一个没有路径的所有文件的新列表。AppleScript 迭代此列表并将其与您指定项目中的名称列表进行比较。如果它发现项目中不存在的文件projectName
,则将projectDst
文件名的路径连接起来,并将其作为参考添加到项目目标中。如果您想将文件复制到库中而不仅仅是作为参考,则需要调整处理程序importToApertureAsReference
或创建一个名为importToApertureAsCopying
or的新处理程序importToApertureAsMoving
。
set inputPath to "Volumes:Kielbasa:Camera:1970 - Fotos" as string
set inputPathHFS to inputPath as alias
log "inputPathHFS: " & inputPathHFS
set projectName to "1970 - Fotos" -- Check this project for duplicates
set projectDst to "AppleScript Import" -- This is where any missing files will be added
set importedList to {}
set inputPathPX to text 1 through -2 of POSIX path of inputPathHFS
log "inputPathPX: " & inputPathPX
set countItemsCommand to "find " & quoted form of inputPathPX & " -type f -maxdepth 1 \\! -name '.*' | wc -l"
set getItemsCommand to "find " & quoted form of inputPathPX & " -type f -maxdepth 1 ! -name '.*' -exec sh -c 'basename \"{}\"' \\;"
set itemCount to (do shell script countItemsCommand) as integer
set itemList to paragraphs of (do shell script getItemsCommand) as list
set missingItemsList to {}
set namesInProjectList to my getAllNamesInProject(projectName) as list
-- Check whether your project contains an object/item (image/video) with the same name
repeat with itemStep from 1 to count of itemList
set thisItem to item itemStep of itemList
log "This Item: " & thisItem
set itemSplit to my splitExtension(thisItem)
set itemName to item 1 of my splitExtension(thisItem)
set itemExt to item 2 of my splitExtension(thisItem)
log "Item Name: " & itemName & ", Item Ext: " & itemExt
log "Checking if project " & projectName & " contains " & itemName
set foundImages to my findAll(namesInProjectList, itemName)
if foundImages is {} then -- if empty, then there is no match so image should be added to Aperture
set end of missingItemsList to contents of thisItem -- this makes a new list of all missing images with extensions (no path), to import into Aperture you need to join this item with its full path
set picAlias to (inputPathHFS as string) & thisItem as alias
log "Importing: " & picAlias
my importToApertureAsReference(picAlias, projectDst)
else
repeat with foundIndex in foundImages
my deleteItem(namesInProjectList, foundIndex)
log "Found Index: " & foundIndex
log "Removed from namesInProjectList: " & thisItem
end repeat
end if
end repeat
return missingItemsList
(*
tell application "System Events"
repeat with itemStep from 1 to count of itemList
set thisItem to item itemStep of itemList
log "This Item: " & thisItem
set itemSplit to my splitExtension(thisItem)
set {itemName, itemExt} to {item 1 of itemSplit, item 2 of itemSplit}
log "Item Name: " & itemName & ", Item Ext: " & itemExt
log "Checking if project " & projectName & " contains " & itemName
-- Compare Lists
if namesInProjectList does not contain itemName then
if otherList does not contain itemName then
-- Generate Alias from filename by joining inputpath and filename
set thisFileAlias to inputPath & ":" & thisItem as alias -- eg "Volumes:Kielbasa:Camera:1970 - Fotos000_0014.jpg"
my importToApertureAsReference(thisFileAlias, projectDst)
log "Imported: " & thisFileAlias
set end of importedList to thisFileAlias
end if
end if
end repeat
end tell
*)
return importedList
on importToApertureAsReference(picAlias, projectName)
log "Importing: " & picAlias
tell application "Aperture"
tell library 1
if not (exists project projectName) then
set projectDst to make new project with properties {name:projectName}
else
set projectDst to project projectName
end if
import picAlias by referencing into projectDst
end tell
end tell
end importToApertureAsReference
on getAllNamesInProject(projectName)
tell application "Aperture"
tell library 1
tell project projectName
set nameList to name of image versions
end tell
end tell
end tell
return nameList
end getAllNamesInProject
on splitExtension(file_name)
set dot to "."
tell AppleScript
set oT to text item delimiters
set text item delimiters to dot
if (count text items of file_name) > 1 then
set out_name to (text items 1 through -2 of file_name) as string
set ext to last text item of file_name
else
set out_name to file_name
set ext to ""
end if
set text item delimiters to oT
if ext is not "" then set ext to dot & ext
return {out_name, ext}
end tell
end splitExtension
on deleteItem(lst, idx)
local lst, idx, len, ndx, l
try
if lst's class is not list then error "not a list." number -1704
script k
property l : lst
end script
set len to count of k's l
set ndx to idx as integer
if ndx is 0 then
error "index 0 is out of range." number -1728
else if ndx < 0 then
set ndx to len + 1 + ndx
if ndx < 1 then error "index " & idx & ¬
" is out of range." number -1728
else if ndx > len then
error "index " & idx & " is out of range." number -1728
end if
if ndx is 1 then
return rest of k's l
else if ndx is len then
return k's l's items 1 thru -2
else
return (k's l's items 1 thru (ndx - 1)) & ¬
(k's l's items (ndx + 1) thru -1)
end if
on error eMsg number eNum
error "Can't deleteItem: " & eMsg number eNum
end try
end deleteItem
on findAll(lst, val)
local lst, val, res
try
if lst's class is not list then error "not a list." number -1704
if {val} is not in lst then return {}
set res to {}
script k
property l : lst
end script
repeat with i from 1 to count of k's l
if k's l's item i is val then set res's end to i
end repeat
return res
on error eMsg number eNum
error "Can't findAll: " & eMsg number eNum
end try
end findAll
Python - 将缺少的文件一一导入项目(使用 AppleScript)
AppleScript 因 13262 张图片的负载而窒息。当 AppleScript 变大时,这些列表对它们来说太多了,所以我决定编写一个 Python 脚本。使用 Python,我可以将两个集合(作为集合的列表)相减,从而创建一个仅包含缺失项的新列表。这消除了再次检查列表中的每个项目的需要另一个列表中的每个项目。它显着加快了该过程。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Imports
import subprocess
from subprocess import Popen, PIPE
import unicodedata
import codecs
import os
inputPath = "/Volumes/Kielbasa/Camera/1970 - Fotos" ## This is the source folder containing all images and videos you want to ensure are in your project (projectOriginal)
projectOriginal = "1970 - Fotos" ## This is where photos from original input are (if you just want to import everything from harddrive one by one, then create an empty project and use it here)
projectDst = "Python Import" ## This is where you will import all of the images and videos that are missing from you project. It is a debugging project (so that you don't screw anything up). You can then drag the images over to the projectOriginal project after ensuring that everything worked correctly.
importedList = []
getItemsCommand = """find '%s' -type f -maxdepth 1 ! -name '.*' -exec sh -c 'basename "{}"' \;""" % inputPath
#subprocess.check_output(*popenargs, **kwargs)
## itemsListEXT is a list of all files in your HD folder with extensions (Aperture projects import filenames without extensions, which I henceforth refer to as names). This list will be used to reconstruct the file paths later. It is important to have this if you have files with different extensions (e.g. images and movies, jpg, jpeg, png, raw)
itemsListEXT = subprocess.check_output(getItemsCommand, shell=True, executable="/bin/bash").splitlines()
itemCount = len(itemsListEXT)
def getItemsInProject(projectOriginal):
cmd = """osascript<<END
tell application "Aperture"
tell library 1
tell project "%s"
return name of image versions
end tell
end tell
end tell
END""" % projectOriginal
itemsListEXT = subprocess.check_output(cmd,shell=True,executable="/bin/bash").split(', ')
return itemsListEXT
## namesInProjectList is a list containing all names of images inside your projectOriginal project.
namesInProjectList = getItemsInProject(projectOriginal)
## namesOnHDList is a list that will be populated with all of the items in itemsListEXT, but without the extensions. The indexes must be the same between these two lists for reconstructing the file paths later.
namesOnHDList = []
for itemStep,thisItem in enumerate(itemsListEXT):
#print itemStep, thisItem.decode('UTF-8')
name,ext = os.path.splitext(thisItem)
namesOnHDList.append(name)
missingItemsList = []
for itemStep,thisItem in enumerate(namesOnHDList):
if thisItem in namesInProjectList:
## Just a place holder
continue
else:
## This reconstructs full paths out of all the missing item names by getting name + extension from itemsListEXT (the indexes in these two lists MUST be the same)
missingItemsList.append(os.path.join(inputPath,itemsListEXT[itemStep]))
## This is for debugging only. You can compare the total number of missing items to the difference between your project and HD items. If that number is the same as the sum of items in missingItemsList, then it is likely working.
print len(missingItemsList)
print missingItemsList
def importToApertureAsReference(objectPath,projectDestination):
scpt = '''
on run {objectPath,projectDestination}
set objectAlias to POSIX file objectPath as alias
set projectName to projectDestination
tell application "Aperture"
tell library 1
if not (exists project projectName) then
set projectDst to make new project with properties {name:projectName}
else
set projectDst to project projectName
end if
import objectAlias by referencing into projectDst
end tell
end tell
end run
'''
args = [objectPath, projectDestination]
p = Popen(['osascript', '-'] + args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate(scpt)
print (p.returncode, stdout, stderr)
print "--> Imported: " + objectPath + " to Project: " + projectDestination
## Add all items from the missingItemsList to your Aperture project destination (projectDst)
countItems = len(missingItemsList)
for itemStep,thisItem in enumerate(missingItemsList):
importToApertureAsReference(thisItem,projectDst)
print "Item: " + str(itemStep) + " of " + str(countItems)
最初发布的 AppleScript
set inputPath to "Volumes:Kielbasa:Camera:1970 - Fotos" as alias
log "inputPath: " & inputPath
set projectName to "1970 - Fotos" -- Check this project for duplicates
set projectDst to "AppleScript Import" -- This is where any missing files will be added
set importedList to {}
set inputPathPX to text 1 through -2 of POSIX path of inputPath
log "inputPathPX: " & inputPathPX
set countItemsCommand to "find " & quoted form of inputPathPX & " -type f \\! -name '.*' | wc -l"
set getItemsCommand to "find " & quoted form of inputPathPX & " -type f ! -name '.*'"
set itemCount to (do shell script countItemsCommand) as integer
set itemList to paragraphs of (do shell script getItemsCommand) as list
set namesList to my getAllNamesInProject(projectName) as list
set otherList to my getAllNamesInProject("Test Project") as list
tell application "System Events"
repeat with itemStep from 1 to count of itemList
tell me to set itemAlias to POSIX file (item itemStep of itemList) as alias
log itemAlias
set itemName to name of itemAlias
set fileNameNOEXT to item 1 of my splitExtension(itemName)
log "Checking if project " & projectName & " contains " & fileNameNOEXT
if namesList does not contain fileNameNOEXT then
if otherList does not contain fileNameNOEXT then
my importToApertureAsReference(itemAlias, projectDst)
set end of importedList to itemAlias
end if
end if
end repeat
end tell
return importedList
on importToApertureAsReference(picAlias, projectName)
log "Importing: " & picAlias
tell application "Aperture"
tell library 1
if not (exists project projectName) then
set projectDst to make new project with properties {name:projectName}
else
set projectDst to project projectName
end if
import picAlias by referencing into projectDst
end tell
end tell
end importToApertureAsReference
on getAllNamesInProject(projectName)
tell application "Aperture"
tell library 1
tell project projectName
set nameList to name of image versions
end tell
end tell
end tell
return nameList
end getAllNamesInProject
on splitExtension(file_name)
set dot to "."
tell AppleScript
set oT to text item delimiters
set text item delimiters to dot
if (count text items of file_name) > 1 then
set out_name to (text items 1 through -2 of file_name) as string
set ext to last text item of file_name
else
set out_name to file_name
set ext to ""
end if
set text item delimiters to oT
if ext is not "" then set ext to dot & ext
return {out_name, ext}
end tell
end splitExtension
提示:如果您单击 AppleScript 编辑器底部的事件或响应选项,您可以查看正在发生的事情(最好在运行脚本之前执行此操作)