Recibo el siguiente error en la aplicación Fotos en mi Mac.
Missing File
Photos with unavailable original files cannot be opened.
The original photo “IMG_3076.JPG” is either offline or cannot be found. Click “Find Original” to reconnect.
Quiero seguir las instrucciones de cómo evitar que se produzca un error de archivo faltante en las fotos , por lo que mi pregunta ahora es:
¿hay alguna forma de obtener todos los archivos faltantes de la biblioteca de Fotos? Será imposible hacer doble clic en cada foto para saber si falta. Solo necesito los directorios, puedo volver a colocarlos uno por uno y consolidar.
Respuesta corta: puede usar el script en este repositorio de GitHub .
Respuesta larga: tenía la misma pregunta, y resulta que la biblioteca de fotos está respaldada por una base de datos SQLite debajo de las sábanas. En su máquina, puede encontrar el archivo de la base de datos en <photo library root>/database/photos.db
. Hay una tabla llamada RKMaster
, con una fila para cada foto y una fileIsReference
columna que te dice si la foto es "externa" o no.
El script al que me vinculé simplemente vuelca la lista de todos los archivos externos y luego itera para verificar que cada uno existe en el disco.
Tenga en cuenta que la tabla también incluye una isMissing
columna, pero esto no es suficiente por sí solo. Solo le informa sobre los archivos que Photos "sabe" que faltan, porque intentó hacer doble clic en ellos o usarlos de alguna manera. Si simplemente elimina un archivo del disco, pero no intenta acceder a él en Fotos, la isMissing
columna será falsa.
Si lo que desea es solo una lista de todos los archivos que faltan, puede obtenerla osxphotos
con el comando
osxphotos query --missing
Eso solo le dará el UUID de cada archivo, no la ruta. Sin embargo, una vez que RepairPhotosBookmarks está integrado OSXphotos
( en breve ), no necesita la ruta del archivo porque esa poderosa aplicación podrá manejar esos archivos faltantes por usted.
OSXphotos
basa en [PhotoScript](github.com/RhetTbull/PhotoScript)
lo que a su vez utiliza la interfaz de script de Apple Photo-Apps. Pero puedo estar equivocado. Sin embargo, me gusta su solución de script porque, si funcionara, sería mucho más fácil de implementar.Descubrí que el indicador isMissing no significa que la imagen se haya ido, solo que no está actualmente en el disco. Usando el script de Python aquí, estaba tratando de copiar todas mis imágenes de Fotos para hacer una copia de seguridad. Me di cuenta de que varias imágenes no se estaban copiando, y resultó que era porque tenían el indicador isMissing en ellas. Pero pude tomar el nombre de la imagen (por ejemplo, IMG_1234.JPG), buscarlo en Fotos y encontró la imagen. Y cuando abrí la imagen en Fotos para verla, se mostraba un círculo de progreso en la esquina inferior derecha (como si estuviera cargando el archivo desde algún lugar), y cuando revisé la carpeta dentro de la biblioteca de Fotos en el disco, efectivamente, el archivo que faltaba ahora estaba allí. Así que ahora el misterio es, ¿dónde están almacenados estos archivos "faltantes" y cómo accedo a ellos (sin tener que visitar todos y cada uno dentro de Fotos)? ¿Alguien ha realizado ingeniería inversa y ha documentado el esquema de Photos SQLLite DB, incluido el significado de los distintos campos? como "falta"? No he sido capaz de encontrarlo yo mismo.
(Nota: la solución parece funcionar solo si la biblioteca de Fotos se ha convertido de una biblioteca de iPhoto más antigua, y las imágenes ya faltaban en ese momento. Lo dejo aquí con fines educativos, pero he agregado otra respuesta con una detección más completa .)
Aquí hay un AppleScript que puede agregar todas las imágenes a Photos.app
un nuevo álbum, desde donde puede seleccionarlas y eliminarlas (por ejemplo, con cmd-delete).
Solo funciona si Fotos ya ha detectado que falta el archivo. No sé qué causa esta detección, es solo que encontré una biblioteca de Fotos donde este era el caso, y luego funcionó este script. Pero cuando traté de reproducir esto con otra biblioteca, donde eliminé los archivos originales (y también me aseguré de que no se recrearan, lo que sucede cuando venían de iCloud), incluso reiniciar Fotos forzando una reparación de la biblioteca no actualizaría las propiedades de la imagen. a un estado en el que mi script los detectaría como perdidos. Tal vez esto solo funcione con bibliotecas que se convirtieron de antiguas bibliotecas de iPhoto (que sé que fue la primera).
Para usarlo, inicie Fotos, cambie para ver todas las fotos y seleccione todas las fotos que desea verificar, por ejemplo, con cmd-A. A continuación, ejecute el script y agregará todas las fotos para las que no haya un archivo de imagen conocido o accesible al álbum de "imágenes faltantes" creado automáticamente.
tell application "Photos"
set media_items to selection
set missing_items to {}
repeat with media_item in media_items
if width of media_item is 0 then
set end of missing_items to media_item
end if
end repeat
if missing_items is {} then
display dialog "Found no missing files" buttons ¬
"OK" default button "OK"
else
if not (exists album "missing images") then
make new album named "missing images"
end if
set dest to album "missing images"
add missing_items to dest
display dialog "Found " & (count of missing_items) & ¬
" missing files" buttons "OK" default button "OK"
end if
end tell
error "Photos got an error: Can't add the provided media items to the album." number 6
Esto sucede independientemente de si a esas fotos les faltan archivos o no.if missing_items is not {} then add missing_items to dest end if
). Por lo tanto, el problema parece estar relacionado con la condición de selección si el ancho de media_item es 0. Aparentemente, la consulta no devuelve 0 cuando el artículo no existe...Nota: La siguiente solución, si bien funciona bien en mi propio caso de prueba, probablemente no sea adecuada para imágenes grandes (100 000) en la biblioteca, ni con fotos descargadas en iCloud. Tome esto como una respuesta educativa, pero no espere que funcione en su caso. Doy la bienvenida a otros a mejorar este script y publicarlo en sus propias respuestas.
El siguiente AppleScript analiza la sqlite
base de datos para identificar las rutas a los archivos y luego verifica si esos archivos están presentes. Si encuentra archivos faltantes, inicia Photos.app e intenta identificar las imágenes (o películas) relacionadas y las agrega a un álbum llamado "imágenes faltantes".
Funciona con las versiones 2 y 3 de la biblioteca de Fotos, probada con Photos.app v3.0 (en macOS 10.13 "High Sierra") y v7.0 (en macOS 12.6 "Montery").
Para usar este script, copie el código a continuación y péguelo en un nuevo documento "Script Editor.app". Si solo desea verificar imágenes específicas en busca de archivos faltantes, abra Fotos y luego seleccione los elementos que desea verificar. De lo contrario, para verificar todos los elementos (fotos, películas), salga de Fotos. Luego ejecute el script. Una vez que el script haya verificado todos los archivos, iniciará Fotos y agregará los elementos faltantes al álbum "imágenes faltantes". Cuando termine, mostrará un mensaje al respecto. Luego puede ver el álbum en Fotos, seleccionar todos los elementos y eliminarlos con cmd-delete si desea deshacerse de ellos.
Sin embargo, tenga en cuenta que si tiene algunas imágenes en medios externos y esos discos no están montados, este script también considerará que faltan; sin embargo, ¡entonces probablemente no desee eliminar esos elementos!
use scripting additions
set path_to_photos_library to POSIX path of (choose file of type ¬
"com.apple.photos.library" with prompt ¬
"Choose the photos library that Photos.app currently uses" default location path to pictures folder)
--
-- Get the current selection from Photos
--
set selectedIDs to {}
if application "Photos" is running then
tell application "Photos"
local media_items
set media_items to selection
repeat with media_item in media_items
set end of selectedIDs to id of media_item
end repeat
quit -- need to quit Photos so that we can access its database
delay 0.5
end tell
end if
--
-- Make sure the database is accessible and determine which DB version to use
--
repeat
try
local files_dir
do shell script "sqlite3 " & quoted form of path_to_photos_library ¬
& "database/photos.db 'SELECT value FROM LiGlobals WHERE keyPath=\"metaSchemaVersion\"'"
ignoring white space
if result = "2" then
set db_version to 2
set files_dir to "Masters"
set db_name to "photos.db"
else if result = "3" then
set db_version to 3
set files_dir to "originals"
set db_name to "Photos.sqlite"
else
my showMessage("Sorry, the database appears to be in an unsupported format.")
quit
end if
end ignoring
set db_path to quoted form of path_to_photos_library & "database/" & db_name
set files_path to path_to_photos_library & files_dir & "/"
delay 0.1
exit repeat
on error
with timeout of 86400 seconds
display dialog "Can't access database - make sure Photos.app is quit, then click OK"
end timeout
end try
end repeat
--
-- Determine the file paths by querying the photos database
--
if selectedIDs is {} then
set where_clause to ""
else
if db_version = 2 then
set where_clause to ¬
" JOIN RKVersion v ON (m.uuid=v.masterUuid)" & ¬
" WHERE v.uuid IN (\"" & joinText(selectedIDs, "\",\"") & "\")"
else
-- need to remove the "/L0/001" suffix from the IDs first
set uuids to {}
repeat with anID in selectedIDs
set end of uuids to first item of splitText(anID, "/")
end repeat
set where_clause to " WHERE ZUUID IN (\"" & joinText(uuids, "\",\"") & "\")"
end if
end if
if db_version = 2 then
set sql to " 'SELECT m.imagePath FROM RKMaster m" & where_clause & "'"
else
set sql to " 'SELECT printf(\"%s/%s\",ZDIRECTORY,ZFILENAME) FROM ZASSET" & where_clause & "'"
end if
do shell script "sqlite3 " & db_path & sql
set check_paths to my splitText(result, return)
delay 0.1
--
-- Check the availability of every file
--
set missing_paths to {}
repeat with relPath in check_paths
set fullPath to (files_path & relPath)
set theFile to POSIX file fullPath
try
(theFile as alias)
on error
set end of missing_paths to relPath as string
end try
end repeat
if missing_paths is {} then
my showMessage("Found no missing files")
quit
end if
--
-- Query the database again to get the ids of the images that reference the missing files
--
with timeout of 86400 seconds
if db_version = 2 then
do shell script "sqlite3 " & db_path & ¬
" 'SELECT v.uuid FROM RKMaster m JOIN RKVersion v ON (m.uuid=v.masterUuid)" & ¬
" WHERE m.imagePath IN (\"" & joinText(missing_paths, "\",\"") & "\")'"
set missing_ids to my splitText(result, return)
else
do shell script "sqlite3 " & db_path & ¬
" 'SELECT ZUUID FROM ZASSET" & ¬
" WHERE printf(\"%s/%s\",ZDIRECTORY,ZFILENAME) IN (\"" & joinText(missing_paths, "\",\"") & "\")'"
set missing_ids to my splitText(result, return)
end if
end timeout
delay 0.1
--
-- Launch Photos, locate the images by their ids and add them to the "missing images" album
--
tell application "Photos"
set unlocated to {}
set missing_items to {}
set all_items to media items
repeat with anID in missing_ids
try
if db_version = 2 then
set anItem to media item id anID
else
set anItem to media item id (anID & "L0/001")
end if
set end of missing_items to anItem
on error
set end of unlocated to anID
end try
end repeat
if missing_items is {} then
my showMessage("Can't locate the images for the missing files." & return & return & ¬
"Make sure you choose the same library that Photos.app currently uses!")
else
if unlocated is not {} then
with timeout of 86400 seconds
display dialog "" & (count of unlocated) & " missing items could not be found in Photos.app" & ¬
return & return & "This means that the script needs to be updated to handle this."
end timeout
end if
if not (exists album "missing images") then
make new album named "missing images"
end if
set dest to album "missing images"
add missing_items to dest
my showMessage("Found " & (count of missing_items) & " missing files")
end if
end tell
--
-- Finished
--
on showMessage(theText)
with timeout of 86400 seconds
display dialog theText buttons "OK" default button "OK"
end timeout
end showMessage
on splitText(theText, theDelimiter)
set old_delimts to AppleScript's text item delimiters
set AppleScript's text item delimiters to theDelimiter
set theTextItems to every text item of theText
set AppleScript's text item delimiters to old_delimts
return theTextItems
end splitText
on joinText(theList, theDelimiter)
set old_delimts to AppleScript's text item delimiters
set AppleScript's text item delimiters to theDelimiter
set theText to theList as string
set AppleScript's text item delimiters to old_delimts
return theText
end joinText
else
script de shell el que está resaltado.osxphotos
aplicación y la interfaz de Python PhotoScript (consulte github.com/RhetTbull/osxphotos y github.com/RhetTbull/PhotoScript , así como mi respuesta a continuación).
Tetsujin
una j