omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    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.


    [solved] duplicate a directory or multiple files.

    Pythonista
    6
    14
    11555
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • jmv38
      jmv38 last edited by jmv38

      thank you all. i did this, for anyone who needs it:

      import os
      import shutil
      cwd = os.getcwd()
      src = '/private/var/mobile/Containers/Shared/AppGroup/blablabla/Documents/FFT' # change for the good adress
      dst = cwd+'/myProg1/FFT'
      print(src)
      print(dst)
      shutil.copytree(src,dst)
      

      however this could be a built-in command of the editor.

      1 Reply Last reply Reply Quote 0
      • jmv38
        jmv38 last edited by

        here are two pieces of code to copy, then paste a directory:

        import editor, clipboard, re, console, os
        
        '''Utilities to be added to the editor
        '''
        def copyDirPathToClipboard():
        	'''Copy current file directory to the clipboard
        	'''
        	# get current location
        	file = editor.get_path()
        	dir = os.path.dirname(file)
        	
        	# inform user and get confirmation
        	msg = re.match('.*Pythonista3/Documents/(.+)',dir).group(1)
        	ans = console.alert('Copy','Copy this directory?\n'+msg+'\nNB: select a file to get its directory!','yes')
        	
        	# if yes, copy to clipboard
        	if ans == 1 :
        	  clipboard.set(dir)
        	  console.hud_alert('Done!','success',0.5)
        	
        copyDirPathToClipboard()
        
        import editor, clipboard, console, re, shutil, os
        
        '''Utility to be added to the editor
        '''
        def pasteDir():
        	'''Copy the directory in clipboard to the same directory as the current file
        	'''
        	# get current directory location
        	file = editor.get_path()
        	dir = os.path.dirname(file)
        	
        	# get source directory from clipboard
        	src = clipboard.get()
        	
        	# get name of directory
        	name = src.split('/')
        	name = name[-1]
        	
        	# build destination name
        	dst = dir + '/' + name
        	
        	# short version of destination
        	msg = re.match('.*Pythonista3/Documents/(.+)',dst).group(1)
        	
        	# if already exists then cancel
        	if os.path.exists(dst):
        		console.alert('Paste Error','Directory:\n'+ msg + '\nalready exists! Paste not possible.')
        
        	# inform user and get confirmation
        	ans = console.alert('Paste','Create this new directory?\n'+msg,'yes')
        	
        	# if yes, paste
        	if ans == 1:
        		shutil.copytree(src,dst)
        		console.hud_alert('Done!','success',0.5)
        	
        	
        pasteDir()
        

        is it possible to add these in the editor wrench menu other than manually?
        Thanks

        1 Reply Last reply Reply Quote 0
        • JonB
          JonB last edited by

          here is a set of tools that can be used for adding /removing items to the wrench menu. I have not tested this in recent versions, let me know if it does not work. You need to save the user defaults after editing.

          1 Reply Last reply Reply Quote 0
          • jmv38
            jmv38 last edited by jmv38

            thank you @JonB
            your code seems ok, however i have type problems.

            I want to check if the action button is not already there before adding it. So i list the action.
            The list of actions is, when i print it

            [<b'__NSCFDictionary': {
                arguments = paste;
                iconName = "Primaries_Paste";
                scriptName = "/myProg1/pasteDir.py";
                title = "paste_dir";
            }>, <b'__NSCFDictionary': {
                arguments = copy;
                iconName = "ios7-copy-outline";
                scriptName = "/myProg1/pasteDir.py";
                title = "copy_dir";
            }
            

            so i create a disctionnary with title keys

            	lst = get_actions()
            	titles = {}
            	for dct in lst:
            		titles[dct['title']] = True
            

            but when i try to access title['copy_dir'] i get a key error.
            i get when i print my dictionnary:

            {<b'NSTaggedPointerString': copy_dir>: True, <b'NSTaggedPointerString': paste_dir>: True}
            

            the maybe the keys are not simple strings?
            so i think i should convert my dct['title'] to strings before using them as key for the dictionnary? But i dont know how to do that, there is no tostring(). Any idea?

            1 Reply Last reply Reply Quote 0
            • JonB
              JonB last edited by JonB

              use str() to convert an NSString to a python string. e.g. str(dct['title'])

              1 Reply Last reply Reply Quote 0
              • jmv38
                jmv38 last edited by jmv38

                @JonB thanks! it does work.
                Here is my final code. Nothing great here, this is just for me to get familiar with python and pythonista.
                paste it where you want, run it, you should have 2 more icons in the wrench menu: copy_dir and paste_dir. There is some limited error management in these 2 function. Only problem: you must select a file in the directory (src or dst) to get the good adress, displaying the good directory is not enough.

                '''This script installs two utilities in the editor:
                	copy directory
                	paste directory
                	Author: Jmv38 - 2016 - Pythonista3
                '''
                import editor, clipboard, console, re, shutil, os
                
                from sys import argv
                
                # this code is from JonB - Thank you!
                # source: https://github.com/jsbain/objc_hacks/blob/master/add_action.py
                
                from objc_util import *
                NSUserDefaults = ObjCClass('NSUserDefaults')
                
                def add_action(scriptName,iconName='python',iconColor='',title='',arguments=''):
                   '''adds an editor action.  scriptName should start with / 
                   (e.g /stash/stash.py)
                   iconName should be an icon without leading prefix, or trailing size.  i.e alert instead of iob:alert_256
                   iconColor should be a web style hex string, eg aa00ff
                   title is the alternative title
                   Call save_defaults() to store defaults
                   ')'''
                   defaults=NSUserDefaults.standardUserDefaults()
                   kwargs=locals()
                   entry={ key:kwargs[key] 
                            for key in
                            ('scriptName','iconName','iconColor','title','arguments') 
                            if key in kwargs and kwargs[key] }
                   editoractions=get_actions()
                   editoractions.append(ns(entry))
                   defaults.setObject_forKey_(editoractions,'EditorActionInfos')
                
                def remove_action(scriptName):
                   ''' remove all instances of a given scriptname.  
                   Call save_defaults() to store for next session
                   '''
                   defaults=NSUserDefaults.standardUserDefaults()
                   editoractions=get_actions()
                   [editoractions.remove(x) for x in editoractions if str(x['scriptName'])==scriptName]
                   defaults.setObject_forKey_(editoractions,'EditorActionInfos')
                   
                def remove_action_at_index(index):
                   ''' remove action at index.  Call save_defaults() to save result.
                   '''
                   defaults=NSUserDefaults.standardUserDefaults()
                   editoractions = get_actions()
                   del editoractions[index]
                   defaults.setObject_forKey_(editoractions,'EditorActionInfos')
                   
                def get_defaults_dict():
                   '''return NSdictionary of defaults'''
                   defaults=NSUserDefaults.standardUserDefaults()
                   return defaults.dictionaryRepresentation()
                   
                def get_actions():
                   '''return action list'''
                   defaults=NSUserDefaults.standardUserDefaults()
                   return list(defaults.arrayForKey_('EditorActionInfos'))
                   
                def save_defaults():
                   '''save current set of defaults'''
                   defaults=NSUserDefaults.standardUserDefaults()
                   NSUserDefaults.setStandardUserDefaults_(defaults)
                   
                # end of JonB code
                
                def install_actions():
                	''' Installs shortcuts in the wrench menu
                	'''
                	# get current location
                	file = editor.get_path()
                	file = re.match('.+Pythonista3/Documents(/.+)',file).group(1)
                	
                	lst = get_actions()
                	titles = {}
                	for dct in lst:
                		titles[str(dct['title'])] = True
                	
                	cmd = 'paste_dir'
                	if cmd not in titles:
                		add_action(arguments = 'paste', 
                		iconName = "Primaries_Paste", 
                		scriptName = file,
                		title = cmd )
                		
                	cmd = 'copy_dir'
                	if cmd not in titles:
                		add_action(arguments = 'copy', 
                		iconName = "ios7-copy-outline", 
                		scriptName = file,
                		title = cmd )
                		
                	save_defaults()
                
                def copyDir():
                	'''Copy current file directory to the clipboard
                	'''
                	# get current location
                	file = editor.get_path()
                	dir = os.path.dirname(file)
                	
                	# inform user and get confirmation
                	msg = re.match('.*Pythonista3/Documents/(.+)',dir).group(1)
                	ans = console.alert('Copy',
                				'\nNB: YOU MUST SELECT A FILE IN THE DIRECTORY TO COPY!'
                				+ '\n\nIs this the directory you want to copy?\n\n' + msg
                				,'yes')
                	
                	# if yes, copy to clipboard
                	if ans == 1 :
                	  clipboard.set(dir)
                	  console.hud_alert('Done!','success',0.5)
                	
                
                def pasteDir():
                	'''Copy the directory in clipboard to the same directory as the current file
                	'''
                	# get current directory location
                	file = editor.get_path()
                	dir = os.path.dirname(file)
                	
                	# get source directory from clipboard
                	src = clipboard.get()
                	
                	# is it a valid source?
                	if not os.path.exists(src):
                		console.alert('Paste Error',
                			'Directory described in clipboard does not exist! Paste not possible.'
                			+ '\nClipboard content:\n\n' + src)
                		return 
                	msg = re.match('.+(Pythonista3/Documents/)(.+)',src)
                	if (msg == None) or (msg.group(2) == None):
                		msg = 'clipboard content is not a valid pythonista3 sub-directory:\n'+src+'\npaste not possible.'
                		console.alert('Paste Error', msg)
                		return
                		
                	# get name of directory
                	name = msg.group(2)
                	name = name.split('/')[-1]
                	
                	# build destination name
                	dst = dir + '/' + name
                	# and a short version
                	msg = re.match('.+(Pythonista3/Documents/)(.+)',dst).group(2)
                	
                	# if already exists then cancel
                	if os.path.exists(dst):
                		console.alert('Paste Error','Directory:\n'+ msg + '\nalready exists! Paste not possible.')
                		return 
                
                	# inform user and get confirmation
                	ans = console.alert('Paste',
                				'\nNB: YOU MUST SELECT A FILE IN THE DIRECTORY WHERE TO PASTE!'
                				+ '\n\nIs this the directory you want to create?\n\n' + msg
                				,'yes')
                	
                	# if yes, paste
                	if ans == 1:
                		shutil.copytree(src,dst)
                		console.hud_alert('Done!','success',0.5)
                
                # get script argument
                cmd = argv[-1]
                if cmd == 'paste':
                	pasteDir()
                elif cmd == 'copy':
                	copyDir()
                else:
                	install_actions()
                	
                	
                
                1 Reply Last reply Reply Quote 0
                • jmv38
                  jmv38 last edited by

                  hello @JonB.
                  using you code for remove_action i found a bug: not all actions were removed. This is due to the dynamic remove of the list elements. I modified your code by adding a reverse scan of the list, and now it is fixed. Thanks.

                  def remove_action(scriptName):
                     ''' remove all instances of a given scriptname.  
                     Call save_defaults() to store for next session
                     '''
                     defaults=NSUserDefaults.standardUserDefaults()
                     editoractions=get_actions()
                     [editoractions.remove(x) for x in reversed(editoractions) if str(x['scriptName'])==scriptName]
                     defaults.setObject_forKey_(editoractions,'EditorActionInfos')
                  
                  1 Reply Last reply Reply Quote 0
                  • jmv38
                    jmv38 last edited by

                    here is the last version of code https://gist.github.com/23407f680c9744ad2beb6d1fafcca9a4
                    it adds 4 shortcuts: copy, paste, dir, file
                    remove the old shortcuts manually.

                    1 Reply Last reply Reply Quote 0
                    • jmv38
                      jmv38 last edited by

                      any one who knows how to get the currently displayed editor directory without selecting a file in this directory?
                      Thanks!

                      1 Reply Last reply Reply Quote 0
                      • dgelessus
                        dgelessus last edited by

                        @jmv38 There is no way to find out what folder is currently shown in Pythonista's file list - there is no function in the editor or console module for that. It might be possible to find this out using objc_util, but I don't know Pythonista's internal structure well enough to help you with that.

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post
                        Powered by NodeBB Forums | Contributors