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
    11552
    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

      Hello there!
      I've just upgraded to pynthonista3. I want to duplicate some of my old files and directories from the pythonista2 to other directories. I cant find the option in the file menu. There seem to be only 'move', and no duplicate. So how would i do that, apart from copying the content of each file one by one? (first page of forum search returned nothing relevant).
      Thanks!

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

        https://docs.python.org/2/library/shutil.html#shutil.copytree or https://docs.python.org/2/library/shutil.html#shutil.move

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

          Use shutil.copytree

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

            You can use stash cp command ("cp f1 f2 f3 destination_directory") to copy multiple files and directory. The stash command "cd ~/../Documents" would take you to top level Pythonista 2 directory. For example "ls ~/../Documents" lists the top level files in pythonista 2 directory and "ls ~/Documents" lists the top level files in pythonista 3 directory. May be you can look at the cp.py in site-packages/stash/bin to see how copy is implemented and it may help you to write your own copy command. Note that cp.py uses shutil.copytree.

            1 Reply Last reply Reply Quote 0
            • 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