Delete photos from camera roll
Is it possible to delete photos from camera roll?
If not, I planned to start a Workflow via its url scheme.
It functions in a normal run of my script but when my script is called by a sharing extension, the webbrowser.open doesn't seem to function.
Can somebody help me?
Thanks a lot
It's theoretically possible to do this via
objc_util, but it's quite complicated actually, so you're probably better off doing it in Workflow.
Opening other apps from app extensions (the share sheet) isn't officially supported (you won't find any app in the App Store that does this), but this happens to work:
from objc_util import nsurl, UIApplication app = UIApplication.sharedApplication() app.openURL_(nsurl('workflow://...'))
It functions but, of course, if I want to perform some steps more after the Execution of my workflow, back in my script, I loose the aspect "share sheet" of my script.
If you could explain how to delete a photo in the script, without any call to Workflow, I would be an happy guy, but perhaps I try a lot of too complicated actions for my first script:
- I run ALLOCINE, kind of French IMDb,
. Where I take a snapshot of the info about a movie
. which, via the share sheet gives me the title of the movie
- in the share sheet, I start my script to
. Get the title of the movie (appex)
. Get the last photo (photos)
. Copy it to my Dropbox with as name, the movie title.png (reason of my first topic about Dropbox in a share sheet script)
. Delete the photo
- I run ALLOCINE, kind of French IMDb,
Okay, here's some code that should delete the most recent photo (after showing a permission dialog; can't change that):
# coding: utf-8 from objc_util import * import threading import photos NSBundle.bundleWithPath_('/System/Library/Frameworks/Photos.framework').load() PHAssetCollection = ObjCClass('PHAssetCollection') PHAsset = ObjCClass('PHAsset') PHPhotoLibrary = ObjCClass('PHPhotoLibrary') PHAssetChangeRequest = ObjCClass('PHAssetChangeRequest') if not photos.is_authorized(): # This shows the photo access permission dialog as a side-effect: photos.get_count() def delete_last_photo(): result = PHAssetCollection.fetchAssetCollectionsWithType_subtype_options_(2, 206, None) coll = result.firstObject() assets = PHAsset.fetchAssetsInAssetCollection_options_(coll, None) a = assets.lastObject() lib = PHPhotoLibrary.sharedPhotoLibrary() def change_block(): req = PHAssetChangeRequest.deleteAssets_([a]) def perform_changes(): lib.performChangesAndWait_error_(change_block, None) t = threading.Thread(target=perform_changes) t.start() t.join() if __name__ == '__main__': delete_last_photo()
Thanks a lot, it's splendid!
You should add it as photos.del_image in a future version...
Hoping I didn't ennoy you too much with my requests 😊
I recognize the code is very complex and that it needs to be a "master" about Photolibrary, collections, type, sub-type, assets etc...If my next request doesn't imply too much work for you, is it possible to delete not only the last photo but photos selected by photos.pick_image. If you think that I exagerate, please don't hesitate to tell me. In any case, thanks for your comprehension.
This is only a little bit off-topic, but what does the skeleton code even do? Like the:
if __name__ == "__main__": # do program and functions here...
Is this specifically for something, or is it just good practice?
I only ask this because I see people do it everywhere, and I've never learned what it does, and if it's useful for something.
sometimes you want to write a script that can be run directly. sometimes you want a module that can be imported.
__main__checks if tou are running the script instead of importing it.
Sometimes you also want both. Some modules in the standard library can be imported (obviously) but are also command-line utilities. For example, you can
import timeitin a script to time Python code programmatically, but you can also run
python -m timeit <code to time>(in a shell) to quickly time the given line of Python code.
I like to put all "main" code of a program inside a
if __name__ == "__main__"block, so just in case I import a script by accident it doesn't start deleting photos from my library.