Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello ā I'm @olemoritz on Twitter.
Listing files from given Files.app directory
-
Hi all,
I really tried to find a similar post that would help me sort my problem out but I didnāt succeed. The question is pretty straightforward - I want to process all of the text files within some (in this case) OneDrive directory mapped in Files.app. I know that because of sandboxing I couldnāt just hardcode the directory path in the script so I guess I would need to ask the user to choose the directory manually each time, but thatās fine. For now the biggest problem is that I have no idea how to set up the document picker dialog to let the user choose a directory instead of a file.
I would appreciate any help :) -
@nizz71 How could you select a folder which has sub-folders?
Actually, tapping on a folder goes down...to display sub-folders or files. -
@nizz71 It should be possible with ObjectiveC UIDocumentPickerViewController to allow multiple selection, select all files of the folder you want and get urls of all files of a folder....
My iPad is French speaking, "tout select" = "select all"
-
@cvp yeah thatās right and thatās exactly what I need to know - can I somehow specify a directory and ādo stuffā with its content?
-
@nizz71 Tomorrow, I'll try...
-
There is a difference between knowing the Path and walking the Path. ā The Matrix
from pathlib import Path def visit(path: Path, depth: int = 0) -> None: for item in path.iterdir(): s = f"{' ' * depth}{item.name}:" if item.is_dir(): print(s) visit(item, depth + 1) else: print(f"{s} {item.stat().st_size:,} bytes") visit(Path("."))
-
import ui from objc_util import * import urllib.parse #===================== delegate of UIDocumentPickerViewController: begin def documentPickerWasCancelled_(_self, _cmd, _controller): #print('documentPickerWasCancelled_') UIDocumentPickerViewController = ObjCInstance(_controller) UIDocumentPickerViewController.uiview.close() if UIDocumentPickerViewController.callback: UIDocumentPickerViewController.callback('canceled') UIDocumentPickerViewController.picked = 'canceled' UIDocumentPickerViewController.done = True def documentPicker_didPickDocumentsAtURLs_(_self, _cmd, _controller, _urls): #print('documentPicker_didPickDocumentsAtURLs_') UIDocumentPickerViewController = ObjCInstance(_controller) UIDocumentPickerViewController.uiview.close() urls = ObjCInstance(_urls) if len(urls) == 1: url = urllib.parse.unquote(str(urls[0])) else: url = [] for i in range(0,len(urls)): url.append(urllib.parse.unquote(str(urls[i]))) if UIDocumentPickerViewController.callback: UIDocumentPickerViewController.callback(url) UIDocumentPickerViewController.picked = url UIDocumentPickerViewController.done = True methods = [documentPicker_didPickDocumentsAtURLs_,documentPickerWasCancelled_] protocols = ['UIDocumentPickerDelegate'] try: MyUIDocumentPickerViewControllerDelegate = ObjCClass('MyUIDocumentPickerViewControllerDelegate') except: MyUIDocumentPickerViewControllerDelegate = create_objc_class('MyUIDocumentPickerViewControllerDelegate', methods=methods, protocols=protocols) #===================== delegate of UIDocumentPickerViewController: end #def handler(_cmd): # print('here') #handler_block = ObjCBlock(handler, restype=None, argtypes=[c_void_p]) @on_main_thread def MyPickDocument(w, h, mode='sheet', popover_location=None, callback=None, title=None, UTIarray=['public.item'], allowsMultipleSelection=False, PickerMode=1,tint_color=None): # view needed for picker uiview = ui.View() uiview.frame = (0,0,w,h) if mode == 'sheet': uiview.present('sheet',hide_title_bar=True) elif mode == 'popover': if popover_location: uiview.present('popover', hide_title_bar=True, popover_location=popover_location) else: return else: return UIDocumentPickerMode = PickerMode # 1 = UIDocumentPickerMode.open # this mode allows a search field # and url in delegate is the original one # 0 = UIDocumentPickerMode.import # url is url of a copy UIDocumentPickerViewController = ObjCClass('UIDocumentPickerViewController').alloc().initWithDocumentTypes_inMode_(UTIarray,UIDocumentPickerMode) #print(dir(UIDocumentPickerViewController)) objc_uiview = ObjCInstance(uiview) SUIViewController = ObjCClass('SUIViewController') vc = SUIViewController.viewControllerForView_(objc_uiview) if title: l = ui.Label() wb = 80 wl = uiview.width - 2*wb # title width #l.border_width = 1 # for tests only l.text = title l.alignment = ui.ALIGN_CENTER # find greatest font size allowing to display title between buttons fs = 16 while True: wt,ht = ui.measure_string(title,font=('Menlo',fs)) if wt <= wl: break fs = fs - 1 l.frame = (wb,0,wl,fs) l.text_color = 'green' UIDocumentPickerViewController.view().addSubview_(ObjCInstance(l)) UIDocumentPickerViewController.setModalPresentationStyle_(3) #currentContext # Use new delegate class: delegate = MyUIDocumentPickerViewControllerDelegate.alloc().init() UIDocumentPickerViewController.delegate = delegate UIDocumentPickerViewController.callback = callback # used by delegate UIDocumentPickerViewController.uiview = uiview # used by delegate UIDocumentPickerViewController.done = False UIDocumentPickerViewController.allowsMultipleSelection = allowsMultipleSelection vc.presentViewController_animated_completion_(UIDocumentPickerViewController, True, None)#handler_block) if tint_color != None: r,g,b = tint_color UIDocumentPickerViewController.view().setTintColor_(ObjCClass('UIColor').colorWithRed_green_blue_alpha_(r,g,b,1.0)) return UIDocumentPickerViewController def main(): # demo code def callback(param): # you could check if file save at hoped place... print(param) MyPickDocument(600,500, callback=callback, title='test', allowsMultipleSelection=True) #MyPickDocument(600,500, mode ='popover', popover_location=(mv.width-40,60)) if __name__ == '__main__': main()
It allows even to select a folder (I didn't know š)
-
@cvp awesome code, works like a charm š now I can choose a directory and get its URL, but.. I still canāt get it to list its content. I feel like I should use FileManager class for it (part of Foundation). I have completely no ObjC background, so Iām a little Daredevilling here, and hereās what I came up with in order to list the content of the chosen directory:
fileManager = ObjCClass("NSFileManager").alloc().init() fileManager.contentsOfDirectoryAtURL_includingPropertiesForKeys_options_error_(param,[],4,None)
where param is the URL of the directory I got from your script. When I run the script it just crashes and Pythonista shuts down. Is pythonās None type the equivalent of ObjC nil? I didnāt know how to pass enumeration options as the third parameter so I just put the default value there (based on the documentation). Could you help me with that as well?
-
print(os.listdir(pathname))
-
Sorry, if you are starting with an nsurl, then you would use nsurl.path() iirc
-
@nizz71 If instead of selecting a directory, you tap it and select all files in this directory, you will get an array with the urls of all files of this folder
['file:///private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/Mes donnees/Pythonista/Backup/Examples/Games/BrickBreaker.py', 'file:///private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/Mes donnees/Pythonista/Backup/Examples/Games/filters.fsh', 'file:///private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/Mes donnees/Pythonista/Backup/Examples/Games/game_levels.py', 'file:///private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/Mes donnees/Pythonista/Backup/Examples/Games/game_menu.py', 'file:///private/var/mobile/Library/Mobile Documents/com~apple~CloudDocs/Mes donnees/Pythonista/Backup/Examples/Games/Match3.py']
-
@nizz71 Yes None = nil
It does not crash with
x = fileManager.contentsOfDirectoryAtPath_error_(param,None)
But returns None, thus that does not help š¢